diff --git a/README.md b/README.md
new file mode 100644
index 0000000..baaa0b6
--- /dev/null
+++ b/README.md
@@ -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).
diff --git a/index.php b/index.php
index 1bbe9c0..66ef2ac 100644
--- a/index.php
+++ b/index.php
@@ -339,16 +339,15 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$replyEmail = trim((string)($config['reply_to'] ?: $config['from_email']));
$replyHref = 'mailto:' . $replyEmail;
- $firstname = trim((string)$config['firstname']) !== '' ? (string)$config['firstname'] : 'zusammen';
$articleRows = '';
if ($count === 0) {
$articleRows = '
-
-
+
+
- |
+ |
Für diesen Zeitraum wurden keine neuen Artikel gefunden.
|
@@ -359,29 +358,29 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
foreach ($articles as $article) {
$articleRows .= '
-
-
+
+
- |
+ |
Thomas-Krenn-Wiki
|
- |
- ' . h($article['title']) . '
+ |
+ ' . h($article['title']) . '
|
- |
+ |
Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '.
|
- |
+ |
@@ -395,10 +394,10 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$testBadge = $isTest
? ' |
- |
+ |
- |
+ |
TESTVERSAND
|
@@ -410,7 +409,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$unsubscribeFooter = '';
$unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? ''));
if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) {
- $unsubscribeFooter = ' | Newsletter abbestellen';
+ $unsubscribeFooter = ' Newsletter abbestellen';
}
$summaryText = $count === 1
@@ -425,79 +424,82 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
Thomas-Krenn Wiki Newsletter
-
+
-
-
-
+
+
-
-
+
+
- |
+ |
Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier.
|
-
- |
+ THOMAS KRENN
+ |
+
+
+
+
+
+ |
+ NEWSLETTER
+ ' . h($periodLabel) . '
+ |
+
+
+ |
+
+
+
- |
- Thomas-Krenn Wiki Newsletter
- |
-
-
- |
- Neue Artikel & spannendes Know-how
- |
-
-
-
- Guten Tag ' . h($firstname) . ',
+ |
+ Guten Tag,
' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis.
+
Viel Spaß beim Lesen wünscht Ihr Team von Thomas-Krenn
|
|
-
' . $testBadge . '
' . $articleRows . '
-
-
-
+ |
+
|
-
-
- Thomas-Krenn Wiki | Technisches Wissen aus der Praxis
- Wiki öffnen' . $unsubscribeFooter . '
+ |
+
+ Thomas-Krenn.AG | Speltenbach-Steinäcker 1 | D-94078 Freyung
+ Wiki öffnen' . $unsubscribeFooter . '
+
|
@@ -520,7 +522,7 @@ function buildPlainText(array $config, array $articles, string $periodLabel, boo
$lines[] = 'Wiki Newsletter';
$lines[] = '';
- $lines[] = 'Servus ' . $config['firstname'] . ',';
+ $lines[] = 'Servus,';
$lines[] = '';
$lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!';
$lines[] = '';
@@ -685,7 +687,7 @@ function configFromPost(array $current): array
'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode',
'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user',
'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) {
@@ -946,8 +948,6 @@ $isLoggedIn = isAdminLoggedIn();
Platzhalter: {MONAT}, {ANZAHL}
-
-
diff --git a/wiki.php b/wiki.php
index 1bbe9c0..19a9f12 100644
--- a/wiki.php
+++ b/wiki.php
@@ -339,16 +339,15 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$replyEmail = trim((string)($config['reply_to'] ?: $config['from_email']));
$replyHref = 'mailto:' . $replyEmail;
- $firstname = trim((string)$config['firstname']) !== '' ? (string)$config['firstname'] : 'zusammen';
$articleRows = '';
if ($count === 0) {
$articleRows = '
-
-
+
+
- |
+ |
Für diesen Zeitraum wurden keine neuen Artikel gefunden.
|
@@ -359,29 +358,29 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
foreach ($articles as $article) {
$articleRows .= '
-
-
+
+
- |
+ |
Thomas-Krenn-Wiki
|
- |
- ' . h($article['title']) . '
+ |
+ ' . h($article['title']) . '
|
- |
+ |
Veröffentlicht am ' . h($article['date_de']) . ' von ' . h($article['author']) . '.
|
- |
+ |
@@ -395,10 +394,10 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$testBadge = $isTest
? ' |
- |
+ |
- |
+ |
TESTVERSAND
|
@@ -410,7 +409,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
$unsubscribeFooter = '';
$unsubscribeUrl = trim((string)($config['unsubscribe_url'] ?? ''));
if ($unsubscribeUrl !== '' && $unsubscribeUrl !== '#' && filter_var($unsubscribeUrl, FILTER_VALIDATE_URL)) {
- $unsubscribeFooter = ' | Newsletter abbestellen';
+ $unsubscribeFooter = ' Newsletter abbestellen';
}
$summaryText = $count === 1
@@ -425,79 +424,82 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
Thomas-Krenn Wiki Newsletter
-
+
-
-
-
+
+
-
-
+
+
- |
+ |
Sollte diese E-Mail nicht einwandfrei dargestellt werden, klicken Sie bitte hier.
|
-
- |
+ THOMAS KRENN
+ |
+
+
+
+
+
+ |
+ NEWSLETTER
+ ' . h($periodLabel) . '
+ |
+
+
+ |
+
+
+
- |
- Thomas-Krenn Wiki Newsletter
- |
-
-
- |
- Neue Artikel & spannendes Know-how
- |
-
-
-
- Guten Tag ' . h($firstname) . ',
+ |
+ Guten Tag,
' . $summaryText . ' Entdecken Sie jetzt alle Neuheiten aus der Welt des Thomas-Krenn-Wikis.
+
Viel Spaß beim Lesen wünscht Ihr Team von Thomas-Krenn
|
|
-
' . $testBadge . '
' . $articleRows . '
-
-
-
+ |
+
|
-
-
- Thomas-Krenn Wiki | Technisches Wissen aus der Praxis
- Wiki öffnen' . $unsubscribeFooter . '
+ |
+
+ Thomas-Krenn.AG | Speltenbach-Steinäcker 1 | D-94078 Freyung
+ Wiki öffnen' . $unsubscribeFooter . '
+
|
@@ -510,6 +512,7 @@ function buildNewsletterHtml(array $config, array $articles, string $periodLabel
}
+
function buildPlainText(array $config, array $articles, string $periodLabel, bool $isTest = false): string
{
$lines = [];
@@ -520,7 +523,7 @@ function buildPlainText(array $config, array $articles, string $periodLabel, boo
$lines[] = 'Wiki Newsletter';
$lines[] = '';
- $lines[] = 'Servus ' . $config['firstname'] . ',';
+ $lines[] = 'Servus,';
$lines[] = '';
$lines[] = 'das Wiki-Team hat im ' . $periodLabel . ' ' . count($articles) . ' Artikel für das Forum veröffentlicht!';
$lines[] = '';
@@ -685,7 +688,7 @@ function configFromPost(array $current): array
'wiki_url', 'article_limit', 'article_fetch_limit', 'period_mode',
'smtp_host', 'smtp_port', 'smtp_encryption', 'smtp_user',
'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) {
@@ -946,8 +949,6 @@ $isLoggedIn = isAdminLoggedIn();
Platzhalter: {MONAT}, {ANZAHL}
-
-
| | | | | | | | | | | | | | | |