FAQ pro Mandant statt fest codiertem AOK-Inhalt
faq.php zeigte bislang fuer jeden Mandanten denselben, komplett AOK-spezifischen Inhalt (Kaffeemaschinen-Bedienung, interner Ansprechpartner) - fuer andere Kunden unbrauchbar und inhaltlich falsch. - Neue Tabelle faq_entries (tenant-scoped, Soft-Delete, sort_order). - Migration uebernimmt die bisherigen AOK-Inhalte einmalig als FAQ des migrierten Default-Mandanten; andere Mandanten sehen sie nicht. - Neue Mandanten bekommen bei der Registrierung automatisch eine kurze generische Starter-FAQ (faq_seed_default_entries), frei editierbar. - faq.php: lesbar fuer alle angemeldeten Mitglieder eines Mandanten, Anlegen/Bearbeiten/Entfernen auf owner/admin beschraenkt. - Landingpage verweist nicht mehr auf faq.php (jetzt interner, mandantengebundener Inhalt statt oeffentlicher Marketing-Seite). Live getestet: AOK-Carry-over fuer Default-Mandant, frisch registrierter Test-Mandant bekam isolierte generische Starter-FAQ, Anlegen mit HTML-Payload (korrekt escaped), Bearbeiten und Soft-Delete geprueft. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+86
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
|
||||
/**
|
||||
* @return list<array{id: int, question: string, answer: string, sort_order: int}>
|
||||
*/
|
||||
function faq_fetch_all(PDO $pdo, int $tenantId): array
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT id, question, answer, sort_order
|
||||
FROM faq_entries
|
||||
WHERE tenant_id = ?
|
||||
AND deleted_at IS NULL
|
||||
ORDER BY sort_order, id'
|
||||
);
|
||||
$stmt->execute([$tenantId]);
|
||||
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
function faq_create(PDO $pdo, int $tenantId, string $question, string $answer): bool
|
||||
{
|
||||
$question = trim($question);
|
||||
$answer = trim($answer);
|
||||
if ($question === '' || $answer === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('SELECT COALESCE(MAX(sort_order), 0) + 1 FROM faq_entries WHERE tenant_id = ? AND deleted_at IS NULL');
|
||||
$stmt->execute([$tenantId]);
|
||||
$nextOrder = (int)$stmt->fetchColumn();
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO faq_entries (tenant_id, question, answer, sort_order) VALUES (?, ?, ?, ?)');
|
||||
|
||||
return $stmt->execute([$tenantId, $question, $answer, $nextOrder]);
|
||||
}
|
||||
|
||||
function faq_update(PDO $pdo, int $tenantId, int $id, string $question, string $answer): bool
|
||||
{
|
||||
$question = trim($question);
|
||||
$answer = trim($answer);
|
||||
if ($question === '' || $answer === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE faq_entries SET question = ?, answer = ? WHERE id = ? AND tenant_id = ? AND deleted_at IS NULL'
|
||||
);
|
||||
$stmt->execute([$question, $answer, $id, $tenantId]);
|
||||
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
function faq_soft_delete(PDO $pdo, int $tenantId, int $id): bool
|
||||
{
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE faq_entries SET deleted_at = NOW() WHERE id = ? AND tenant_id = ? AND deleted_at IS NULL'
|
||||
);
|
||||
$stmt->execute([$id, $tenantId]);
|
||||
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seeds a small, generic starter FAQ for a brand-new tenant (mirrors the
|
||||
* excerpt already shown on the public landing page), so new customers do
|
||||
* not start with a completely empty FAQ. They can edit or delete every
|
||||
* entry afterwards.
|
||||
*/
|
||||
function faq_seed_default_entries(PDO $pdo, int $tenantId): void
|
||||
{
|
||||
$starters = [
|
||||
['Wie starten wir mit unserer Kaffeeliste?', 'Mitglieder unter „Mitglieder verwalten" anlegen, danach direkt Striche und Einzahlungen erfassen. Es ist keine weitere Einrichtung nötig.'],
|
||||
['Wer kann Mitglieder verwalten oder Einstellungen ändern?', 'Das hängt von der zugewiesenen Rolle ab: Administrator und Kassenwart können Buchungen vornehmen, nur Administrator und Inhaber können Einstellungen und Zugänge verwalten.'],
|
||||
['Können wir per PayPal bezahlen?', 'Ja, wenn PayPal in den Mandant-Einstellungen aktiviert ist. Einzahlungen lassen sich zusätzlich jederzeit manuell erfassen.'],
|
||||
['Wie erfahre ich meinen aktuellen Stand?', 'Im eigenen Dashboard unter „Meine Kaffeeliste" ist der aktuelle Stand jederzeit sichtbar.'],
|
||||
];
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO faq_entries (tenant_id, question, answer, sort_order) VALUES (?, ?, ?, ?)');
|
||||
foreach ($starters as $index => [$question, $answer]) {
|
||||
$stmt->execute([$tenantId, $question, $answer, $index + 1]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user