Single frequency setting; per-user override; footer line

Admin-facing simplification:
- Dropped separate \"lookahead\" and \"historical lookahead\" tree
  prefs (and the once-per-month historical gate). A single
  \"send every N days\" number now drives both the cron cadence
  and the window each issue looks ahead for living + deceased
  events.
- Default 14, range 1–90, applies uniformly.

User-facing addition:
- The /my-account/{tree} subscription card gained an \"Email
  frequency\" select with options: use site default, weekly,
  every 2 weeks, monthly, every 2 months, quarterly. Stored as
  a per-tree-per-user preference.
- Dispatch now checks each recipient's own cadence against
  their own last-sent timestamp. Admin-added external addresses
  with no webtrees account always receive every run (no
  per-user state).
- Newsletter footer now reads \"You can change how often you
  receive this email, or unsubscribe entirely, in the Newsletter
  subscription section on your My account page\" — true now
  that the control exists.

German translations updated for the new strings; stale ones
removed.
This commit is contained in:
2026-05-15 14:12:39 +02:00
parent 355a888e3b
commit 00478e2466
7 changed files with 162 additions and 122 deletions
+11 -14
View File
@@ -108,9 +108,9 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
'Subscribe to the newsletter' => 'Newsletter abonnieren',
'Send newsletters every' => 'Newsletter senden alle',
'days' => 'Tage',
'Look ahead' => 'Vorschau',
'Each issue looks the same number of days ahead, for both living relatives and historical events of those who have passed away. Default 14.'
=> 'Jede Ausgabe blickt um die gleiche Anzahl Tage in die Zukunft, sowohl für lebende Verwandte als auch für historische Ereignisse bereits verstorbener Personen. Standardwert 14.',
'Include marriage anniversaries' => 'Hochzeitstage einbeziehen',
'Historical look-ahead (days)' => 'Historische Vorschau (Tage)',
'Extra recipient email addresses (one per line)' => 'Zusätzliche Empfänger-E-Mail-Adressen (eine pro Zeile)',
'Subject prefix' => 'Betreff-Präfix',
'Save' => 'Speichern',
@@ -141,15 +141,20 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
=> 'Sie erhalten regelmäßig eine E-Mail mit anstehenden Geburtstagen und weiteren Familienereignissen aus %s.',
'You are receiving this email because you subscribed to the %s newsletter.'
=> 'Sie erhalten diese E-Mail, weil Sie den Newsletter „%s“ abonniert haben.',
'To change or cancel your subscription, edit the “Newsletter subscription” section on your %s page.'
=> 'Um Ihr Abonnement zu ändern oder zu kündigen, bearbeiten Sie den Abschnitt „Newsletter-Abonnement“ auf Ihrer Seite %s.',
'You can change how often you receive this email, or unsubscribe entirely, in the “Newsletter subscription” section on your %s page.'
=> 'Wie oft Sie diese E-Mail erhalten oder ob Sie sie ganz abbestellen möchten können Sie im Abschnitt „Newsletter-Abonnement“ auf Ihrer Seite %s ändern.',
'Email frequency' => 'E-Mail-Häufigkeit',
'Use site default (every %d days)' => 'Standard der Seite verwenden (alle %d Tage)',
'Weekly' => 'Wöchentlich',
'Every 2 weeks' => 'Alle 2 Wochen',
'Monthly' => 'Monatlich',
'Every 2 months' => 'Alle 2 Monate',
'Quarterly' => 'Vierteljährlich',
'Configure newsletter dispatch on a per-tree basis. The sender is the contact user of each tree (falling back to the site webmaster).'
=> 'Newsletter-Versand pro Stammbaum konfigurieren. Absender ist die Kontaktperson des jeweiligen Baums (alternativ der Webmaster der Seite).',
'Enable newsletter for this tree' => 'Newsletter für diesen Baum aktivieren',
'Only intact marriages of still-living couples are included.'
=> 'Nur bestehende Ehen lebender Paare werden berücksichtigt.',
'Births and deaths of deceased people are included once per calendar month.'
=> 'Geburten und Todestage verstorbener Personen werden einmal pro Kalendermonat einbezogen.',
'Last sent: %s' => 'Zuletzt gesendet: %s',
'Configure your system cron, systemd timer, or any external scheduler to call the URL below. The schedule decides when newsletters are actually due — calling more frequently is safe.'
=> 'Richten Sie System-Cron, systemd-Timer oder einen externen Scheduler so ein, dass er die untenstehende URL aufruft. Der Versandplan entscheidet, wann tatsächlich gesendet wird — häufiger aufrufen ist unbedenklich.',
@@ -231,12 +236,6 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
$frequency = Validator::parsedBody($request)
->isBetween(Configuration::MIN_FREQUENCY_DAYS, Configuration::MAX_FREQUENCY_DAYS)
->integer('frequency-' . $id, Configuration::DEFAULT_FREQUENCY_DAYS);
$lookahead = Validator::parsedBody($request)
->isBetween(Configuration::MIN_LOOKAHEAD_DAYS, Configuration::MAX_LOOKAHEAD_DAYS)
->integer('lookahead-' . $id, Configuration::DEFAULT_LOOKAHEAD_DAYS);
$histLook = Validator::parsedBody($request)
->isBetween(7, 60)
->integer('historical-' . $id, Configuration::DEFAULT_HISTORICAL_LOOKAHEAD);
$lineal = Validator::parsedBody($request)
->isBetween(Configuration::MIN_LINEAL_DEPTH, Configuration::MAX_LINEAL_DEPTH)
->integer('lineal-' . $id, Configuration::DEFAULT_LINEAL_DEPTH);
@@ -246,8 +245,6 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
$tree->setPreference(Configuration::PREF_ENABLED, $enabled ? '1' : '0');
$tree->setPreference(Configuration::PREF_FREQUENCY_DAYS, (string) $frequency);
$tree->setPreference(Configuration::PREF_LOOKAHEAD_DAYS, (string) $lookahead);
$tree->setPreference(Configuration::PREF_HISTORICAL_LOOKAHEAD, (string) $histLook);
$tree->setPreference(Configuration::PREF_LINEAL_DEPTH, (string) $lineal);
$tree->setPreference(Configuration::PREF_INCLUDE_ANNIVERSARIES, $annivs ? '1' : '0');
$tree->setPreference(Configuration::PREF_EXTRA_RECIPIENTS, $extras);