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
+5 -7
View File
@@ -16,9 +16,7 @@ use Illuminate\Support\Collection;
* @var Collection<int,Fact>|null $anniversaries
* @var Collection<int,Fact>|null $historical
* @var bool $include_anniversaries
* @var bool $include_historical
* @var int $lookahead_days
* @var int $historical_lookahead
* @var int $window_days Shared lookahead window for living + deceased events
* @var int $generated_at
* @var array<string,string> $avatar_cids xref => CID name
* @var array<string,string> $relationships xref => "your mother" etc. (per-recipient)
@@ -597,7 +595,7 @@ $timeline_arrow_row = '<tr>'
<div style="font-size:13px;font-weight:300;color:<?= $palette['ink3'] ?>;">
<?= e($masthead_date($generated_at)) ?>
<span style="color:<?= $palette['mute'] ?>;">·</span>
<?= e(I18N::translate('Events in the next %d days.', $lookahead_days)) ?>
<?= e(I18N::translate('Events in the next %d days.', $window_days)) ?>
</div>
</td>
</tr>
@@ -706,7 +704,7 @@ $timeline_arrow_row = '<tr>'
</td></tr>
<?php endif ?>
<?php if ($include_historical && $historical !== null && !$historical->isEmpty()) : ?>
<?php if ($historical !== null && !$historical->isEmpty()) : ?>
<?php
$detailed = [];
$summary = [];
@@ -717,7 +715,7 @@ $timeline_arrow_row = '<tr>'
<tr><td style="padding:32px 0 0;">
<h2 style="<?= $section_title_style ?>"><?= e(I18N::translate('On this month in history')) ?></h2>
<p style="<?= $section_kicker_style ?>">
<?= e(I18N::translate('Events in the next %d days for people who have passed away.', $historical_lookahead)) ?>
<?= e(I18N::translate('Events in the next %d days for people who have passed away.', $window_days)) ?>
</p>
<?php if ($detailed !== []) : ?>
<?= $card_open ?>
@@ -764,7 +762,7 @@ $timeline_arrow_row = '<tr>'
<?= e(I18N::translate('You are receiving this email because you subscribed to the %s newsletter.', $tree->title())) ?>
<br>
<?= I18N::translate(
'To change or cancel your subscription, edit the “Newsletter subscription” section on your %s page.',
'You can change how often you receive this email, or unsubscribe entirely, in the “Newsletter subscription” section on your %s page.',
'<a href="' . e($account_url) . '" style="color:' . $palette['link'] . ';text-decoration:none;border-bottom:1px solid ' . $palette['link'] . ';">' . e(I18N::translate('My account')) . '</a>',
) ?>
</p>