Refactor newsletter HTML structure and styles for improved readability and consistency. Adjusted padding, colors, and font sizes across various elements. Updated unsubscribe link styling and background color for better visibility.

This commit is contained in:
smueller
2026-07-07 10:23:47 +02:00
parent f9a711766c
commit 87cd80b3d8
3 changed files with 191 additions and 116 deletions

74
README.md Normal file
View File

@@ -0,0 +1,74 @@
# Newsletter Generator (TK Wiki)
Dieses Tool erzeugt aus den neuesten Artikeln im Thomas-Krenn-Wiki einen HTML-Newsletter, bietet eine Vorschau im Browser und versendet per SMTP (inkl. Testversand und optionalem Cron-Lauf).
## Voraussetzungen
- PHP 8.1+ (empfohlen)
- PHP-Erweiterungen:
- `curl`
- `json`
- `mbstring`
- `openssl`
- optional: `dom` (bessere Artikel-Erkennung)
- Composer
- SMTP-Zugangsdaten
## Installation
1. Projekt auf den Webserver kopieren.
2. Im Projektordner Abhängigkeiten installieren:
```bash
composer install
```
3. Admin-Passwort setzen:
- In `index.php` (und ggf. `wiki.php`) die Konstante `ADMIN_PASSWORD` ändern.
- Standardwert `CHANGE_ME_ADMIN_PASSWORD` **nicht** produktiv verwenden.
4. Webserver auf den Projektordner zeigen lassen (Document Root).
## Erste Einrichtung im Browser
1. Datei im Browser öffnen:
- z. B. `https://deine-domain.tld/index.php`
2. SMTP- und Newsletter-Felder ausfüllen:
- SMTP Host, Port, Verschlüsselung, Benutzer/Passwort
- Absender (`from_email`, `from_name`)
- Empfänger (`recipient_email`, optional `test_recipient_email`)
3. Auf **Einstellungen speichern** klicken.
4. Mit **Vorschau erzeugen** Layout prüfen.
5. Mit **Testnewsletter senden** Testversand durchführen.
## Monatlicher Versand per Cron
Das Tool unterstützt einen tokenbasierten Cron-Endpunkt.
- Token wird im Admin-Bereich unter **Cron Token** angezeigt/gesetzt.
- CLI-Beispiel:
```bash
php index.php --cron --token='DEIN_CRON_TOKEN'
```
- Web-Cron-Beispiel:
```bash
curl -fsS 'https://deine-domain.tld/index.php?cron=DEIN_CRON_TOKEN' > /dev/null
```
Hinweis: Der Monatsnewsletter wird pro Zeitraum nur einmal versendet (Status in `newsletter-state.json`).
## Wichtige Dateien
- `index.php` Hauptdatei (Admin, Vorschau, Versand, Cron)
- `wiki.php` parallele Variante mit gleicher Funktionalität
- `newsletter-config.json` gespeicherte Konfiguration
- `newsletter-state.json` Versandstatus pro Monat
## Sicherheitshinweise
- `ADMIN_PASSWORD` immer sofort ändern.
- Projekt nicht öffentlich zugänglich lassen, wenn kein Login aktiv ist.
- SMTP-Zugangsdaten im Dateisystem schützen (Dateirechte/Backup-Zugriff).

116
index.php
View File

@@ -339,16 +339,15 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$replyEmail = trim((string)($config['reply_to'] ?: $config['from_email'])); $replyEmail = trim((string)($config['reply_to'] ?: $config['from_email']));
$replyHref = 'mailto:' . $replyEmail; $replyHref = 'mailto:' . $replyEmail;
$firstname = trim((string)$config['firstname']) !== '' ? (string)$config['firstname'] : 'zusammen';
$articleRows = ''; $articleRows = '';
if ($count === 0) { if ($count === 0) {
$articleRows = ' $articleRows = '
<tr> <tr>
<td style="padding:0 34px 18px 34px;" class="mobile-padding"> <td style="padding:0 20px 18px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#f8fbff;border:1px solid #d9e6f4;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;border:1px solid #d9d9d9;">
<tr> <tr>
<td style="padding:22px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:24px;color:#2c3e50;"> <td style="padding:18px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Für diesen Zeitraum wurden keine neuen Artikel gefunden. Für diesen Zeitraum wurden keine neuen Artikel gefunden.
</td> </td>
</tr> </tr>
@@ -359,29 +358,29 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
foreach ($articles as $article) { foreach ($articles as $article) {
$articleRows .= ' $articleRows .= '
<tr> <tr>
<td style="padding:0 34px 18px 34px;" class="mobile-padding"> <td style="padding:0 20px 14px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;border:1px solid #dfe5eb;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;">
<tr> <tr>
<td style="padding:18px 20px 6px 20px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;color:#6b7f94;"> <td style="padding:0 0 4px 0;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px;color:#444444;">
Thomas-Krenn-Wiki Thomas-Krenn-Wiki
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 8px 20px;font-family:Arial,Helvetica,sans-serif;font-size:23px;line-height:30px;font-weight:700;color:#164194;"> <td style="padding:0 0 6px 0;font-family:Arial,Helvetica,sans-serif;font-size:22px;line-height:28px;font-weight:700;color:#ef7d00;">
<a href="' . h($article['url']) . '" target="_blank" style="color:#164194;text-decoration:none;">' . h($article['title']) . '</a> <a href="' . h($article['url']) . '" target="_blank" style="color:#ef7d00;text-decoration:none;">' . h($article['title']) . '</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 12px 20px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#3f4d5f;"> <td style="padding:0 0 10px 0;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '. Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '.
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 20px 20px;"> <td style="padding:0 0 2px 0;">
<table role="presentation" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td bgcolor="#ef7d00" style="background-color:#ef7d00;border-radius:3px;"> <td bgcolor="#ef7d00" style="background-color:#ef7d00;">
<a href="' . h($article['url']) . '" target="_blank" style="display:inline-block;padding:11px 18px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:18px;font-weight:700;color:#ffffff;text-decoration:none;">Jetzt Artikel lesen</a> <a href="' . h($article['url']) . '" target="_blank" style="display:inline-block;padding:8px 14px;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:17px;color:#ffffff;text-decoration:none;">Jetzt Artikel lesen</a>
</td> </td>
</tr> </tr>
</table> </table>
@@ -395,10 +394,10 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$testBadge = $isTest $testBadge = $isTest
? '<tr> ? '<tr>
<td style="padding:0 34px 16px 34px;" class="mobile-padding"> <td style="padding:0 20px 14px 20px;" class="mobile-padding">
<table role="presentation" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td bgcolor="#fff3cd" style="background-color:#fff3cd;border:1px solid #f4d58a;padding:6px 10px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;letter-spacing:0.6px;color:#7a5200;"> <td bgcolor="#fff3cd" style="background-color:#fff3cd;border:1px solid #f4d58a;padding:6px 10px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;color:#7a5200;">
TESTVERSAND TESTVERSAND
</td> </td>
</tr> </tr>
@@ -410,7 +409,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$unsubscribeFooter = ''; $unsubscribeFooter = '';
$unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? '')); $unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? ''));
if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) { if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) {
$unsubscribeFooter = ' &nbsp;|&nbsp; <a href="' . h($unsubscribeUrl) . '" target="_blank" style="color:#66788b;text-decoration:underline;">Newsletter abbestellen</a>'; $unsubscribeFooter = '<br><a href="' . h($unsubscribeUrl) . '" target="_blank" style="color:#ef7d00;text-decoration:underline;">Newsletter abbestellen</a>';
} }
$summaryText = $count === 1 $summaryText = $count === 1
@@ -425,79 +424,82 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Thomas-Krenn Wiki Newsletter</title> <title>Thomas-Krenn Wiki Newsletter</title>
<style type="text/css"> <style type="text/css">
html, body { margin:0 !important; padding:0 !important; width:100% !important; background:#f2f5f8; } html, body { margin:0 !important; padding:0 !important; width:100% !important; background:#e9e9e9; }
table, td { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } table, td { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }
img { border:0; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic; } img { border:0; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic; }
a { text-decoration:none; } a { text-decoration:none; }
* { -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%; } * { -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%; }
.preheader { display:none !important; visibility:hidden; opacity:0; color:transparent; height:0; width:0; max-height:0; max-width:0; overflow:hidden; mso-hide:all; } .preheader { display:none !important; visibility:hidden; opacity:0; color:transparent; height:0; width:0; max-height:0; max-width:0; overflow:hidden; mso-hide:all; }
@media only screen and (max-width: 680px) { @media only screen and (max-width: 640px) {
.email-container { width:100% !important; } .email-container { width:100% !important; }
.mobile-padding { padding-left:18px !important; padding-right:18px !important; } .mobile-padding { padding-left:14px !important; padding-right:14px !important; }
.mobile-header { padding:24px 18px 18px 18px !important; } .mobile-text { font-size:15px !important; line-height:22px !important; }
.mobile-title { font-size:26px !important; line-height:32px !important; } .mobile-title { font-size:24px !important; line-height:30px !important; }
.mobile-text { font-size:16px !important; line-height:24px !important; }
} }
</style> </style>
</head> </head>
<body style="margin:0;padding:0;background-color:#f2f5f8;"> <body style="margin:0;padding:0;background-color:#e9e9e9;">
<div class="preheader">' . h($preheader) . '&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;</div> <div class="preheader">' . h($preheader) . '&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;</div>
<center role="article" aria-roledescription="email" lang="de" style="width:100%;background-color:#e9e9e9;">
<center role="article" aria-roledescription="email" lang="de" style="width:100%;background-color:#f2f5f8;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#e9e9e9" style="width:100%;background-color:#e9e9e9;">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#f2f5f8" style="width:100%;background-color:#f2f5f8;">
<tr> <tr>
<td align="center" style="padding:22px 10px;"> <td align="center" style="padding:10px;">
<table role="presentation" width="680" border="0" cellspacing="0" cellpadding="0" class="email-container" bgcolor="#ffffff" style="width:100%;max-width:680px;background-color:#ffffff;border:1px solid #dce3ea;"> <table role="presentation" width="620" border="0" cellspacing="0" cellpadding="0" class="email-container" bgcolor="#ffffff" style="width:100%;max-width:620px;background-color:#ffffff;">
<tr> <tr>
<td class="mobile-padding" style="padding:14px 34px;border-bottom:1px solid #e4e9ef;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;color:#6f8092;"> <td align="center" style="padding:10px 20px 8px 20px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:16px;color:#555555;">
Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier. Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier.
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="mobile-header" style="padding:26px 34px 20px 34px;"> <td align="center" style="padding:6px 20px 10px 20px;font-family:Arial,Helvetica,sans-serif;font-size:26px;line-height:30px;font-weight:700;color:#555555;letter-spacing:0.5px;">
THOMAS KRENN
</td>
</tr>
<tr>
<td style="padding:0 20px 0 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background:#1f2d3d;">
<tr>
<td style="padding:16px 14px;font-family:Arial,Helvetica,sans-serif;color:#ffffff;">
<div style="font-size:13px;line-height:18px;font-weight:700;letter-spacing:0.6px;color:#ef7d00;">NEWSLETTER</div>
<div style="font-size:22px;line-height:28px;font-weight:700;">' . h($periodLabel) . '</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="padding:12px 20px 8px 20px;" class="mobile-padding mobile-text">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td style="padding:0 0 12px 0;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;font-weight:700;letter-spacing:0.9px;text-transform:uppercase;color:#6b7f94;"> <td style="font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:23px;color:#222222;">
Thomas-Krenn Wiki Newsletter Guten Tag,<br><br>
</td>
</tr>
<tr>
<td class="mobile-title" style="padding:0 0 8px 0;font-family:Arial,Helvetica,sans-serif;font-size:32px;line-height:38px;font-weight:700;color:#164194;">
Neue Artikel & spannendes Know-how
</td>
</tr>
<tr>
<td class="mobile-text" style="padding:0;font-family:Arial,Helvetica,sans-serif;font-size:16px;line-height:25px;color:#2f3c4d;">
Guten Tag ' . h($firstname) . ',<br><br>
' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis. ' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis.
<br><br>Viel Spaß beim Lesen wünscht<br>Ihr Team von Thomas-Krenn
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
' . $testBadge . ' ' . $testBadge . '
' . $articleRows . ' ' . $articleRows . '
<tr> <tr>
<td class="mobile-padding" style="padding:0 34px 24px 34px;"> <td style="padding:6px 20px 18px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#f8fafc;border:1px solid #dde4eb;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;">
<tr> <tr>
<td style="padding:18px 20px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:23px;color:#354355;"> <td style="font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Viel Spaß beim Lesen wünscht Ihr Team von Thomas-Krenn.<br><br>
Haben Sie Fragen oder einen Themenwunsch? Haben Sie Fragen oder einen Themenwunsch?
<a href="' . h($replyHref) . '" style="color:#164194;text-decoration:underline;">Kontaktieren Sie uns gerne direkt.</a> <a href="' . h($replyHref) . '" style="color:#ef7d00;text-decoration:underline;">Kontaktieren Sie uns gerne direkt.</a>
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:20px 34px;background-color:#f6f8fb;border-top:1px solid #dfe6ee;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:19px;color:#66788b;text-align:center;"> <td style="background:#ececec;padding:18px 20px;font-family:Arial,Helvetica,sans-serif;text-align:center;">
Thomas-Krenn Wiki &nbsp;|&nbsp; Technisches Wissen aus der Praxis<br> <div style="font-size:12px;line-height:19px;color:#666666;">
<a href="https://www.thomas-krenn.com/de/wiki/Hauptseite" target="_blank" style="color:#66788b;text-decoration:underline;">Wiki öffnen</a>' . $unsubscribeFooter . ' Thomas-Krenn.AG | Speltenbach-Steinäcker 1 | D-94078 Freyung<br>
<a href="https://www.thomas-krenn.com/de/wiki/Hauptseite" target="_blank" style="color:#ef7d00;text-decoration:underline;">Wiki öffnen</a>' . $unsubscribeFooter . '
</div>
</td> </td>
</tr> </tr>
</table> </table>
@@ -520,7 +522,7 @@ function buildPlainText(array $config, array $articles, string $periodLabel, boo
$lines[] = 'Wiki Newsletter'; $lines[] = 'Wiki Newsletter';
$lines[] = ''; $lines[] = '';
$lines[] = 'Servus ' . $config['firstname'] . ','; $lines[] = 'Servus,';
$lines[] = ''; $lines[] = '';
$lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!'; $lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!';
$lines[] = ''; $lines[] = '';
@@ -685,7 +687,7 @@ function configFromPost(array $current): array
'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode', 'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode',
'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user', 'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user',
'from_email', 'from_name', 'recipient_email', 'test_recipient_email', 'from_email', 'from_name', 'recipient_email', 'test_recipient_email',
'subject', 'firstname', 'reply_to', 'unsubscribe_url', 'cron_token' 'subject', 'reply_to', 'unsubscribe_url', 'cron_token'
]; ];
foreach ($fields as $field) { foreach ($fields as $field) {
@@ -946,8 +948,6 @@ $isLoggedIn = isAdminLoggedIn();
<input name="subject" value="<?= h($config['subject']) ?>"> <input name="subject" value="<?= h($config['subject']) ?>">
<p class="hint">Platzhalter: <code>{MONAT}</code>, <code>{ANZAHL}</code></p> <p class="hint">Platzhalter: <code>{MONAT}</code>, <code>{ANZAHL}</code></p>
<label>Vorname / Anrede</label>
<input name="firstname" value="<?= h($config['firstname']) ?>">
</section> </section>
<section class="card"> <section class="card">

117
wiki.php
View File

@@ -339,16 +339,15 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$replyEmail = trim((string)($config['reply_to'] ?: $config['from_email'])); $replyEmail = trim((string)($config['reply_to'] ?: $config['from_email']));
$replyHref = 'mailto:' . $replyEmail; $replyHref = 'mailto:' . $replyEmail;
$firstname = trim((string)$config['firstname']) !== '' ? (string)$config['firstname'] : 'zusammen';
$articleRows = ''; $articleRows = '';
if ($count === 0) { if ($count === 0) {
$articleRows = ' $articleRows = '
<tr> <tr>
<td style="padding:0 34px 18px 34px;" class="mobile-padding"> <td style="padding:0 20px 18px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#f8fbff;border:1px solid #d9e6f4;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;border:1px solid #d9d9d9;">
<tr> <tr>
<td style="padding:22px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:24px;color:#2c3e50;"> <td style="padding:18px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Für diesen Zeitraum wurden keine neuen Artikel gefunden. Für diesen Zeitraum wurden keine neuen Artikel gefunden.
</td> </td>
</tr> </tr>
@@ -359,29 +358,29 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
foreach ($articles as $article) { foreach ($articles as $article) {
$articleRows .= ' $articleRows .= '
<tr> <tr>
<td style="padding:0 34px 18px 34px;" class="mobile-padding"> <td style="padding:0 20px 14px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;border:1px solid #dfe5eb;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#ffffff;">
<tr> <tr>
<td style="padding:18px 20px 6px 20px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;letter-spacing:0.5px;text-transform:uppercase;color:#6b7f94;"> <td style="padding:0 0 4px 0;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px;color:#444444;">
Thomas-Krenn-Wiki Thomas-Krenn-Wiki
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 8px 20px;font-family:Arial,Helvetica,sans-serif;font-size:23px;line-height:30px;font-weight:700;color:#164194;"> <td style="padding:0 0 6px 0;font-family:Arial,Helvetica,sans-serif;font-size:22px;line-height:28px;font-weight:700;color:#ef7d00;">
<a href="' . h($article['url']) . '" target="_blank" style="color:#164194;text-decoration:none;">' . h($article['title']) . '</a> <a href="' . h($article['url']) . '" target="_blank" style="color:#ef7d00;text-decoration:none;">' . h($article['title']) . '</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 12px 20px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#3f4d5f;"> <td style="padding:0 0 10px 0;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '. Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '.
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:0 20px 20px 20px;"> <td style="padding:0 0 2px 0;">
<table role="presentation" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td bgcolor="#ef7d00" style="background-color:#ef7d00;border-radius:3px;"> <td bgcolor="#ef7d00" style="background-color:#ef7d00;">
<a href="' . h($article['url']) . '" target="_blank" style="display:inline-block;padding:11px 18px;font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:18px;font-weight:700;color:#ffffff;text-decoration:none;">Jetzt Artikel lesen</a> <a href="' . h($article['url']) . '" target="_blank" style="display:inline-block;padding:8px 14px;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:17px;color:#ffffff;text-decoration:none;">Jetzt Artikel lesen</a>
</td> </td>
</tr> </tr>
</table> </table>
@@ -395,10 +394,10 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$testBadge = $isTest $testBadge = $isTest
? '<tr> ? '<tr>
<td style="padding:0 34px 16px 34px;" class="mobile-padding"> <td style="padding:0 20px 14px 20px;" class="mobile-padding">
<table role="presentation" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td bgcolor="#fff3cd" style="background-color:#fff3cd;border:1px solid #f4d58a;padding:6px 10px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;letter-spacing:0.6px;color:#7a5200;"> <td bgcolor="#fff3cd" style="background-color:#fff3cd;border:1px solid #f4d58a;padding:6px 10px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:15px;font-weight:700;color:#7a5200;">
TESTVERSAND TESTVERSAND
</td> </td>
</tr> </tr>
@@ -410,7 +409,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$unsubscribeFooter = ''; $unsubscribeFooter = '';
$unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? '')); $unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? ''));
if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) { if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) {
$unsubscribeFooter = ' &nbsp;|&nbsp; <a href="' . h($unsubscribeUrl) . '" target="_blank" style="color:#66788b;text-decoration:underline;">Newsletter abbestellen</a>'; $unsubscribeFooter = '<br><a href="' . h($unsubscribeUrl) . '" target="_blank" style="color:#ef7d00;text-decoration:underline;">Newsletter abbestellen</a>';
} }
$summaryText = $count === 1 $summaryText = $count === 1
@@ -425,79 +424,82 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Thomas-Krenn Wiki Newsletter</title> <title>Thomas-Krenn Wiki Newsletter</title>
<style type="text/css"> <style type="text/css">
html, body { margin:0 !important; padding:0 !important; width:100% !important; background:#f2f5f8; } html, body { margin:0 !important; padding:0 !important; width:100% !important; background:#e9e9e9; }
table, td { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } table, td { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }
img { border:0; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic; } img { border:0; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic; }
a { text-decoration:none; } a { text-decoration:none; }
* { -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%; } * { -ms-text-size-adjust:100%; -webkit-text-size-adjust:100%; }
.preheader { display:none !important; visibility:hidden; opacity:0; color:transparent; height:0; width:0; max-height:0; max-width:0; overflow:hidden; mso-hide:all; } .preheader { display:none !important; visibility:hidden; opacity:0; color:transparent; height:0; width:0; max-height:0; max-width:0; overflow:hidden; mso-hide:all; }
@media only screen and (max-width: 680px) { @media only screen and (max-width: 640px) {
.email-container { width:100% !important; } .email-container { width:100% !important; }
.mobile-padding { padding-left:18px !important; padding-right:18px !important; } .mobile-padding { padding-left:14px !important; padding-right:14px !important; }
.mobile-header { padding:24px 18px 18px 18px !important; } .mobile-text { font-size:15px !important; line-height:22px !important; }
.mobile-title { font-size:26px !important; line-height:32px !important; } .mobile-title { font-size:24px !important; line-height:30px !important; }
.mobile-text { font-size:16px !important; line-height:24px !important; }
} }
</style> </style>
</head> </head>
<body style="margin:0;padding:0;background-color:#f2f5f8;"> <body style="margin:0;padding:0;background-color:#e9e9e9;">
<div class="preheader">' . h($preheader) . '&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;</div> <div class="preheader">' . h($preheader) . '&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;</div>
<center role="article" aria-roledescription="email" lang="de" style="width:100%;background-color:#e9e9e9;">
<center role="article" aria-roledescription="email" lang="de" style="width:100%;background-color:#f2f5f8;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#e9e9e9" style="width:100%;background-color:#e9e9e9;">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#f2f5f8" style="width:100%;background-color:#f2f5f8;">
<tr> <tr>
<td align="center" style="padding:22px 10px;"> <td align="center" style="padding:10px;">
<table role="presentation" width="680" border="0" cellspacing="0" cellpadding="0" class="email-container" bgcolor="#ffffff" style="width:100%;max-width:680px;background-color:#ffffff;border:1px solid #dce3ea;"> <table role="presentation" width="620" border="0" cellspacing="0" cellpadding="0" class="email-container" bgcolor="#ffffff" style="width:100%;max-width:620px;background-color:#ffffff;">
<tr> <tr>
<td class="mobile-padding" style="padding:14px 34px;border-bottom:1px solid #e4e9ef;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;color:#6f8092;"> <td align="center" style="padding:10px 20px 8px 20px;font-family:Arial,Helvetica,sans-serif;font-size:11px;line-height:16px;color:#555555;">
Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier. Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier.
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="mobile-header" style="padding:26px 34px 20px 34px;"> <td align="center" style="padding:6px 20px 10px 20px;font-family:Arial,Helvetica,sans-serif;font-size:26px;line-height:30px;font-weight:700;color:#555555;letter-spacing:0.5px;">
THOMAS KRENN
</td>
</tr>
<tr>
<td style="padding:0 20px 0 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background:#1f2d3d;">
<tr>
<td style="padding:16px 14px;font-family:Arial,Helvetica,sans-serif;color:#ffffff;">
<div style="font-size:13px;line-height:18px;font-weight:700;letter-spacing:0.6px;color:#ef7d00;">NEWSLETTER</div>
<div style="font-size:22px;line-height:28px;font-weight:700;">' . h($periodLabel) . '</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="padding:12px 20px 8px 20px;" class="mobile-padding mobile-text">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr> <tr>
<td style="padding:0 0 12px 0;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;font-weight:700;letter-spacing:0.9px;text-transform:uppercase;color:#6b7f94;"> <td style="font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:23px;color:#222222;">
Thomas-Krenn Wiki Newsletter Guten Tag,<br><br>
</td>
</tr>
<tr>
<td class="mobile-title" style="padding:0 0 8px 0;font-family:Arial,Helvetica,sans-serif;font-size:32px;line-height:38px;font-weight:700;color:#164194;">
Neue Artikel & spannendes Know-how
</td>
</tr>
<tr>
<td class="mobile-text" style="padding:0;font-family:Arial,Helvetica,sans-serif;font-size:16px;line-height:25px;color:#2f3c4d;">
Guten Tag ' . h($firstname) . ',<br><br>
' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis. ' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis.
<br><br>Viel Spaß beim Lesen wünscht<br>Ihr Team von Thomas-Krenn
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
' . $testBadge . ' ' . $testBadge . '
' . $articleRows . ' ' . $articleRows . '
<tr> <tr>
<td class="mobile-padding" style="padding:0 34px 24px 34px;"> <td style="padding:6px 20px 18px 20px;" class="mobile-padding">
<table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;background-color:#f8fafc;border:1px solid #dde4eb;border-radius:4px;"> <table role="presentation" width="100%" border="0" cellspacing="0" cellpadding="0" style="width:100%;">
<tr> <tr>
<td style="padding:18px 20px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:23px;color:#354355;"> <td style="font-family:Arial,Helvetica,sans-serif;font-size:14px;line-height:22px;color:#333333;">
Viel Spaß beim Lesen wünscht Ihr Team von Thomas-Krenn.<br><br>
Haben Sie Fragen oder einen Themenwunsch? Haben Sie Fragen oder einen Themenwunsch?
<a href="' . h($replyHref) . '" style="color:#164194;text-decoration:underline;">Kontaktieren Sie uns gerne direkt.</a> <a href="' . h($replyHref) . '" style="color:#ef7d00;text-decoration:underline;">Kontaktieren Sie uns gerne direkt.</a>
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="padding:20px 34px;background-color:#f6f8fb;border-top:1px solid #dfe6ee;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:19px;color:#66788b;text-align:center;"> <td style="background:#ececec;padding:18px 20px;font-family:Arial,Helvetica,sans-serif;text-align:center;">
Thomas-Krenn Wiki &nbsp;|&nbsp; Technisches Wissen aus der Praxis<br> <div style="font-size:12px;line-height:19px;color:#666666;">
<a href="https://www.thomas-krenn.com/de/wiki/Hauptseite" target="_blank" style="color:#66788b;text-decoration:underline;">Wiki öffnen</a>' . $unsubscribeFooter . ' Thomas-Krenn.AG | Speltenbach-Steinäcker 1 | D-94078 Freyung<br>
<a href="https://www.thomas-krenn.com/de/wiki/Hauptseite" target="_blank" style="color:#ef7d00;text-decoration:underline;">Wiki öffnen</a>' . $unsubscribeFooter . '
</div>
</td> </td>
</tr> </tr>
</table> </table>
@@ -510,6 +512,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
} }
function buildPlainText(array $config, array $articles, string $periodLabel, bool $isTest = false): string function buildPlainText(array $config, array $articles, string $periodLabel, bool $isTest = false): string
{ {
$lines = []; $lines = [];
@@ -520,7 +523,7 @@ function buildPlainText(array $config, array $articles, string $periodLabel, boo
$lines[] = 'Wiki Newsletter'; $lines[] = 'Wiki Newsletter';
$lines[] = ''; $lines[] = '';
$lines[] = 'Servus ' . $config['firstname'] . ','; $lines[] = 'Servus,';
$lines[] = ''; $lines[] = '';
$lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!'; $lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!';
$lines[] = ''; $lines[] = '';
@@ -685,7 +688,7 @@ function configFromPost(array $current): array
'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode', 'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode',
'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user', 'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user',
'from_email', 'from_name', 'recipient_email', 'test_recipient_email', 'from_email', 'from_name', 'recipient_email', 'test_recipient_email',
'subject', 'firstname', 'reply_to', 'unsubscribe_url', 'cron_token' 'subject', 'reply_to', 'unsubscribe_url', 'cron_token'
]; ];
foreach ($fields as $field) { foreach ($fields as $field) {
@@ -946,8 +949,6 @@ $isLoggedIn = isAdminLoggedIn();
<input name="subject" value="<?= h($config['subject']) ?>"> <input name="subject" value="<?= h($config['subject']) ?>">
<p class="hint">Platzhalter: <code>{MONAT}</code>, <code>{ANZAHL}</code></p> <p class="hint">Platzhalter: <code>{MONAT}</code>, <code>{ANZAHL}</code></p>
<label>Vorname / Anrede</label>
<input name="firstname" value="<?= h($config['firstname']) ?>">
</section> </section>
<section class="card"> <section class="card">