Files
webtrees_email_newsletter/resources/views/admin.phtml
T
Alexander 9ccc636105 Admin user roster; per-locale subject; SiteUser as From
- Admin preferences page can now subscribe existing webtrees users
  per tree, not just external addresses.
- Subject prefix is now configurable per locale (en/de), and the
  date in the subject is formatted via IntlDateFormatter in the
  recipient's locale.
- "From:" header now uses SiteUser (SMTP_FROM_NAME/SMTP_DISP_NAME)
  to match webtrees' own system-mail convention; the tree contact
  becomes the Reply-To.
2026-05-15 14:30:01 +02:00

251 lines
13 KiB
PHTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
use EmailNewsletter\Configuration;
use EmailNewsletter\Module;
use Fisharebest\Webtrees\Http\RequestHandlers\ControlPanel;
use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAllPage;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Tree;
use Fisharebest\Webtrees\User;
use Illuminate\Support\Collection;
/**
* @var Module $module
* @var Collection<int,Tree> $all_trees
* @var Collection<int,User> $all_users
* @var string $cron_token
* @var string $cron_url
* @var string $title
*/
?>
<?= view('components/breadcrumbs', [
'links' => [
route(ControlPanel::class) => I18N::translate('Control panel'),
route(ModulesAllPage::class) => I18N::translate('Modules'),
$title,
],
]) ?>
<h1><?= e($title) ?></h1>
<p>
<?= I18N::translate('Configure newsletter dispatch on a per-tree basis. The sender is the contact user of each tree (falling back to the site webmaster).') ?>
</p>
<form method="post">
<?= csrf_field() ?>
<?php foreach ($all_trees as $tree) : ?>
<?php
$id = $tree->id();
$enabled = Configuration::isEnabled($tree);
$frequency = Configuration::frequencyDays($tree);
$annivs = Configuration::includeAnniversaries($tree);
$subject = Configuration::subjectPrefix($tree);
$extras = $tree->getPreference(Configuration::PREF_EXTRA_RECIPIENTS, '');
$lineal = Configuration::linealDepth($tree);
$last_sent = Configuration::lastSentAt($tree);
?>
<fieldset class="card mb-4">
<legend class="card-header h4"><?= e($tree->title()) ?></legend>
<div class="card-body">
<div class="row mb-3">
<div class="offset-sm-3 col-sm-9">
<div class="form-check">
<input class="form-check-input" type="checkbox"
id="enabled-<?= $id ?>" name="enabled-<?= $id ?>"
value="1" <?= $enabled ? 'checked' : '' ?>>
<label class="form-check-label" for="enabled-<?= $id ?>">
<?= I18N::translate('Enable newsletter for this tree') ?>
</label>
</div>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-3 col-form-label" for="frequency-<?= $id ?>">
<?= I18N::translate('Send newsletters every') ?>
</label>
<div class="col-sm-9">
<div class="input-group" style="max-width: 18rem;">
<input class="form-control" type="number"
id="frequency-<?= $id ?>" name="frequency-<?= $id ?>"
value="<?= e((string) $frequency) ?>"
min="<?= Configuration::MIN_FREQUENCY_DAYS ?>"
max="<?= Configuration::MAX_FREQUENCY_DAYS ?>" required>
<span class="input-group-text"><?= I18N::translate('days') ?></span>
</div>
<small class="form-text text-muted">
<?= I18N::translate('Each issue looks the same number of days ahead, for both living relatives and historical events of those who have passed away. Default 14.') ?>
</small>
</div>
</div>
<div class="row mb-3">
<div class="offset-sm-3 col-sm-9">
<div class="form-check">
<input class="form-check-input" type="checkbox"
id="anniversaries-<?= $id ?>" name="anniversaries-<?= $id ?>"
value="1" <?= $annivs ? 'checked' : '' ?>>
<label class="form-check-label" for="anniversaries-<?= $id ?>">
<?= I18N::translate('Include marriage anniversaries') ?>
</label>
</div>
<small class="form-text text-muted">
<?= I18N::translate('Only intact marriages of still-living couples are included.') ?>
</small>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-3 col-form-label" for="lineal-<?= $id ?>">
<?= I18N::translate('Detailed view distance') ?>
</label>
<div class="col-sm-9">
<input class="form-control" type="number" style="max-width: 18rem;"
id="lineal-<?= $id ?>" name="lineal-<?= $id ?>"
value="<?= e((string) $lineal) ?>"
min="<?= Configuration::MIN_LINEAL_DEPTH ?>"
max="<?= Configuration::MAX_LINEAL_DEPTH ?>" required>
<small class="form-text text-muted">
<?= I18N::translate('A person is shown in detail (avatar, icon, timeline) when they sit within this many descent-steps of the recipient\'s direct lineage. Examples relative to the recipient: a sibling is distance 1 (one step down from the recipient\'s parent), a great-aunt is distance 1 (one step down from a great-grandparent), a nephew is distance 2, a first cousin is distance 2. Spouses share their partner\'s distance. Everyone outside this radius appears as a compact text bullet at the bottom of each section. Set to 0 to render the whole newsletter as text; recipients with no linked tree record always see the full detailed view.') ?>
</small>
</div>
</div>
<fieldset class="row mb-3">
<legend class="col-sm-3 col-form-label">
<?= I18N::translate('Subject prefix') ?>
</legend>
<div class="col-sm-9">
<small class="form-text text-muted d-block mb-2">
<?= I18N::translate('Prepended to the email subject line. Leave a field blank to fall back to the generic prefix below.') ?>
</small>
<?php foreach (Configuration::supportedSubjectLocales() as $code => $label) : ?>
<?php
$field = 'subject-' . $id . '-' . $code;
$val = $tree->getPreference(
Configuration::PREF_SUBJECT_PREFIX_PREFIX . $code,
'',
);
?>
<div class="input-group input-group-sm mb-2">
<span class="input-group-text" style="min-width: 7rem;">
<?= e($label) ?>
</span>
<input class="form-control" type="text"
id="<?= e($field) ?>" name="<?= e($field) ?>"
value="<?= e($val) ?>"
placeholder="<?= e('[' . $tree->title() . '] ') ?>">
</div>
<?php endforeach ?>
<div class="input-group input-group-sm">
<span class="input-group-text" style="min-width: 7rem;">
<?= I18N::translate('Generic') ?>
</span>
<input class="form-control" type="text"
id="subject-<?= $id ?>" name="subject-<?= $id ?>"
value="<?= e($subject) ?>">
</div>
</div>
</fieldset>
<div class="row mb-3">
<label class="col-sm-3 col-form-label" for="extras-<?= $id ?>">
<?= I18N::translate('Extra recipient email addresses (one per line)') ?>
</label>
<div class="col-sm-9">
<textarea class="form-control" rows="4"
id="extras-<?= $id ?>" name="extras-<?= $id ?>"><?= e($extras) ?></textarea>
</div>
</div>
<div class="row mb-3">
<label class="col-sm-3 col-form-label">
<?= I18N::translate('Subscribed users') ?>
</label>
<div class="col-sm-9">
<input type="hidden" name="users-submitted-<?= $id ?>" value="1">
<?php if ($all_users->isEmpty()) : ?>
<small class="form-text text-muted">
<?= I18N::translate('No users with email addresses found.') ?>
</small>
<?php else : ?>
<small class="form-text text-muted d-block mb-2">
<?= I18N::translate('Tick a user to subscribe them to this trees newsletter. Users can still adjust their own subscription on their account page.') ?>
</small>
<div class="border rounded p-2"
style="max-height: 18rem; overflow-y: auto;">
<?php foreach ($all_users as $user) : ?>
<?php
$field = 'subscribe-' . $id . '-' . $user->id();
$is_subbed = $tree->getUserPreference($user, Configuration::USER_PREF_SUBSCRIBED) === '1';
?>
<div class="form-check">
<input class="form-check-input" type="checkbox"
id="<?= e($field) ?>" name="<?= e($field) ?>"
value="1" <?= $is_subbed ? 'checked' : '' ?>>
<label class="form-check-label" for="<?= e($field) ?>">
<?= e($user->realName()) ?>
<small class="text-muted">
&lt;<?= e($user->email()) ?>&gt;
</small>
</label>
</div>
<?php endforeach ?>
</div>
<?php endif ?>
</div>
</div>
<?php if ($last_sent > 0) : ?>
<div class="row mb-3">
<div class="offset-sm-3 col-sm-9">
<small class="text-muted">
<?= I18N::translate('Last sent: %s', date('Y-m-d H:i', $last_sent)) ?>
</small>
</div>
</div>
<?php endif ?>
</div>
</fieldset>
<?php endforeach ?>
<fieldset class="card mb-4">
<legend class="card-header h4"><?= I18N::translate('Cron token') ?></legend>
<div class="card-body">
<p>
<?= I18N::translate('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.') ?>
</p>
<pre class="bg-light p-2"><?= e($cron_url) ?></pre>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="regenerate_token"
name="regenerate_token" value="1">
<label class="form-check-label" for="regenerate_token">
<?= I18N::translate('Regenerate token') ?>
</label>
</div>
</div>
</fieldset>
<button type="submit" class="btn btn-primary">
<?= view('icons/save') ?>
<?= I18N::translate('Save') ?>
</button>
</form>
<form method="post" action="<?= e(route('module', ['module' => $module->name(), 'action' => 'SendNowAdmin'])) ?>" class="mt-3">
<?= csrf_field() ?>
<button type="submit" class="btn btn-secondary"
onclick="return confirm('<?= e(I18N::translate('Send the newsletter now for every enabled tree?')) ?>');">
<?= I18N::translate('Send now') ?>
</button>
</form>