Feat: onglet SMTP dans l'administration

- Formulaire d'édition des paramètres SMTP (serveur, port, chiffrement,
  utilisateur, mot de passe, expéditeur) stockés dans data/smtp_settings.json
  (écrit par www-data, contrairement au .env en lecture seule)
- Test de connexion SMTP avec logs PHPMailer complets (DEBUG_SERVER)
- Envoi d'email de test avec contenu personnalisé anti-spam
- src/SmtpSettings.php : lecture/écriture smtp_settings.json avec fallback env()
- mailer.php : lit les paramètres depuis SmtpSettings en priorité
- admin.js : indicateurs spinner sur les boutons pendant le traitement
This commit is contained in:
Cedric Abonnel
2026-05-13 10:53:03 +02:00
parent 4cc4a01534
commit 26ada9b54e
5 changed files with 377 additions and 8 deletions
+152
View File
@@ -52,6 +52,10 @@ function adminStatusBadge(array $a, int $now): string
<a class="nav-link <?= $tab === 'comments' ? 'active' : '' ?>"
href="/admin/comments">Commentaires</a>
</li>
<li class="nav-item">
<a class="nav-link <?= $tab === 'smtp' ? 'active' : '' ?>"
href="/admin/smtp">SMTP</a>
</li>
<?php endif; ?>
</ul>
@@ -461,6 +465,154 @@ function adminStatusBadge(array $a, int $now): string
<?php endif; ?>
<!-- ─────────────────────────── SMTP ─────────────────────────────── -->
<?php if ($tab === 'smtp' && isAdmin()): ?>
<?php $sc = $adminData['smtp_config']; ?>
<?php if (isset($_GET['saved'])): ?>
<div class="alert alert-success py-2 mb-3">Paramètres SMTP enregistrés.</div>
<?php endif; ?>
<div class="row g-4">
<!-- Formulaire config + actions -->
<div class="col-lg-5">
<div class="card">
<div class="card-header">Configuration SMTP</div>
<div class="card-body">
<form method="post" id="smtp-config-form">
<div class="mb-3">
<label for="smtp-host" class="form-label small fw-semibold">Serveur</label>
<input type="text" id="smtp-host" name="smtp_host"
class="form-control form-control-sm font-monospace"
value="<?= htmlspecialchars($sc['host']) ?>"
placeholder="smtp.exemple.fr">
</div>
<div class="row g-2 mb-3">
<div class="col-5">
<label for="smtp-port" class="form-label small fw-semibold">Port</label>
<input type="number" id="smtp-port" name="smtp_port"
class="form-control form-control-sm"
value="<?= htmlspecialchars($sc['port']) ?>"
placeholder="587" min="1" max="65535">
</div>
<div class="col-7">
<label for="smtp-secure" class="form-label small fw-semibold">Chiffrement</label>
<select id="smtp-secure" name="smtp_secure" class="form-select form-select-sm">
<option value="" <?= $sc['secure'] === '' ? 'selected' : '' ?>>Aucun</option>
<option value="tls" <?= strtolower($sc['secure']) === 'tls' ? 'selected' : '' ?>>STARTTLS (587)</option>
<option value="ssl" <?= strtolower($sc['secure']) === 'ssl' ? 'selected' : '' ?>>SSL/TLS (465)</option>
</select>
</div>
</div>
<div class="mb-3">
<label for="smtp-user" class="form-label small fw-semibold">Utilisateur</label>
<input type="text" id="smtp-user" name="smtp_user"
class="form-control form-control-sm"
value="<?= htmlspecialchars($sc['user']) ?>"
placeholder="user@exemple.fr"
autocomplete="off">
</div>
<div class="mb-3">
<label for="smtp-pass" class="form-label small fw-semibold">Mot de passe</label>
<input type="password" id="smtp-pass" name="smtp_pass"
class="form-control form-control-sm"
placeholder="<?= $sc['has_pass'] ? '(inchangé si vide)' : '' ?>"
autocomplete="new-password">
<?php if ($sc['has_pass']): ?>
<div class="form-text">Laisser vide pour conserver le mot de passe actuel.</div>
<?php endif; ?>
</div>
<div class="mb-3">
<label for="smtp-from" class="form-label small fw-semibold">Email expéditeur</label>
<input type="email" id="smtp-from" name="smtp_from"
class="form-control form-control-sm"
value="<?= htmlspecialchars($sc['from']) ?>"
placeholder="no-reply@exemple.fr">
</div>
<div class="mb-3">
<label for="smtp-from-name" class="form-label small fw-semibold">Nom expéditeur</label>
<input type="text" id="smtp-from-name" name="smtp_from_name"
class="form-control form-control-sm"
value="<?= htmlspecialchars($sc['from_name']) ?>"
placeholder="Mon Site">
</div>
<div class="d-flex flex-wrap gap-2">
<button type="submit" formaction="/?action=admin_smtp_save"
class="btn btn-primary btn-sm" id="smtp-save-btn">
Enregistrer
</button>
<button type="submit" formaction="/?action=admin_smtp_test"
name="mode" value="connect"
class="btn btn-outline-secondary btn-sm">
Tester la connexion
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Envoi de test + résultats -->
<div class="col-lg-7">
<div class="card mb-3">
<div class="card-body">
<form method="post" action="/?action=admin_smtp_test" id="smtp-test-form">
<input type="hidden" name="mode" value="send">
<label for="smtp-email" class="form-label small fw-semibold">Envoyer un email de test</label>
<div class="d-flex gap-2">
<input type="email" id="smtp-email" name="test_email"
class="form-control form-control-sm"
placeholder="destinataire@exemple.fr"
value="<?= htmlspecialchars($adminData['smtp_test']['email'] ?? '') ?>"
required>
<button type="submit" class="btn btn-outline-secondary btn-sm text-nowrap" id="smtp-send-btn">
Envoyer
</button>
</div>
</form>
</div>
</div>
<?php if (isset($adminData['smtp_test'])): ?>
<?php $st = $adminData['smtp_test']; ?>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span>
<?php if ($st['success']): ?>
<span class="text-success fw-semibold">✓ Succès</span>
<?php else: ?>
<span class="text-danger fw-semibold">✗ Échec</span>
<?php endif; ?>
<?= $st['mode'] === 'send'
? 'Envoi vers ' . htmlspecialchars($st['email'])
: 'Test de connexion' ?>
</span>
<span class="text-muted small"><?= htmlspecialchars($st['ts']) ?></span>
</div>
<?php if (!$st['success'] && $st['error'] !== ''): ?>
<div class="alert alert-danger mb-0 rounded-0 border-0 border-bottom py-2 px-3 small">
<?= htmlspecialchars($st['error']) ?>
</div>
<?php endif; ?>
<?php if (!empty($st['logs'])): ?>
<pre class="p-3 mb-0 small" style="max-height:420px;overflow-y:auto;font-size:0.75rem;background:var(--vl-code-bg,#f8f9fa);border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)"><?php
foreach ($st['logs'] as $line) {
echo htmlspecialchars($line) . "\n";
}
?></pre>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<script src="/assets/js/admin.js" defer></script>
<?php endif; ?>
<!-- ─────────────────────────── COMMENTAIRES ──────────────────────── -->
<?php if ($tab === 'comments' && isAdmin()): ?>