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>
87 lines
3.2 KiB
PHP
87 lines
3.2 KiB
PHP
<?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]);
|
|
}
|
|
}
|