Beide Module wurden aus einem anderen Kundenprojekt kopiert und bereinigt: Knowledgecenter: - Bild-Cache (1.985 Dateien) geleert, Ordnerstruktur mit .gitkeep behalten - Files-Gallery-Lizenzschlüssel entfernt (config.php) - Kundenspezifische Kategorien gelöscht: Teil I/II/III QM-Struktur, nummerierte QM-Kapitel, Gremien (Präsidium/Finanzausschuss/Landesausschuss), Sitzungsservice-Serie, Protokoll-Abteilungen, Testeinträge - 56 generische Kategorien bleiben (Downloads, Onboarding, Personalthemen …) Tasks: - Alle Betriebsdaten gelöscht (114 Tasks, 914 Submissions, 579 Assignments) - Task-Definitionen und Verlinkungen geleert - Kategoriestruktur bleibt (Allgemein, IT, Personal, Buchhaltung …) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
147 lines
4.7 KiB
PHP
147 lines
4.7 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once dirname(dirname(__DIR__)) . '/bootstrap.php';
|
|
|
|
if (TaskCertRequest::method() !== 'GET') {
|
|
TaskCertResponse::error('Methode nicht erlaubt', 405, false);
|
|
}
|
|
|
|
$auth = TaskCertAuthContext::fromGlobals();
|
|
if (!$auth->hasPermission('r-task-cert-admin')) {
|
|
TaskCertResponse::error('Keine Berechtigung', 403, false);
|
|
}
|
|
|
|
$csrfToken = TaskCertRequest::queryString('csrf_token', '');
|
|
if (!TaskCertCsrf::validate($csrfToken)) {
|
|
TaskCertResponse::error('CSRF validation failed', 419, false);
|
|
}
|
|
|
|
$taskId = TaskCertRequest::queryInt('id', 0);
|
|
if ($taskId <= 0) {
|
|
TaskCertResponse::error('Ungültige Aufgaben-ID.', 400, false);
|
|
}
|
|
|
|
$services = task_cert_services();
|
|
$task = $services['definitionRepo']->findById($taskId);
|
|
if ($task === null) {
|
|
TaskCertResponse::error('Aufgabe nicht gefunden.', 404, false);
|
|
}
|
|
|
|
// Aktive Methoden (mit Feld-/Quiz-/Beitragskonfiguration) laden — analog zur
|
|
// echten User-Detailseite (actions/user/task_detail_action.php).
|
|
$methods = $services['ruleRepo']->getMethodsByTask($taskId);
|
|
$methods = array_values(array_filter($methods, static function (array $method): bool {
|
|
return (int) ($method['active'] ?? 1) === 1;
|
|
}));
|
|
|
|
// Beitragstitel für knowledge_read-Methoden auflösen.
|
|
$postIds = [];
|
|
foreach ($methods as $method) {
|
|
if ((string) ($method['method_type'] ?? '') !== 'knowledge_read') {
|
|
continue;
|
|
}
|
|
foreach ((array) ($method['knowledge_posts'] ?? []) as $post) {
|
|
$postId = (int) ($post['knowledge_post_id'] ?? 0);
|
|
if ($postId > 0) {
|
|
$postIds[] = $postId;
|
|
}
|
|
}
|
|
}
|
|
|
|
$knowledgePostTitleMap = [];
|
|
$lookupService = $services['lookupService'] ?? null;
|
|
if ($lookupService instanceof TaskLookupService && $postIds !== []) {
|
|
$languageId = (int) ($GLOBALS['language']['id'] ?? 1);
|
|
$knowledgePostTitleMap = $lookupService->getKnowledgePostTitleMapByIds($languageId, $postIds);
|
|
}
|
|
|
|
foreach ($methods as &$method) {
|
|
if ((string) ($method['method_type'] ?? '') !== 'knowledge_read') {
|
|
continue;
|
|
}
|
|
foreach ((array) ($method['knowledge_posts'] ?? []) as &$post) {
|
|
$postId = (int) ($post['knowledge_post_id'] ?? 0);
|
|
$post['title'] = $knowledgePostTitleMap[$postId] ?? ('Beitrag #' . $postId);
|
|
}
|
|
unset($post);
|
|
}
|
|
unset($method);
|
|
|
|
$responsibles = $services['ruleRepo']->getResponsiblesWithContactData($taskId);
|
|
|
|
// Eigene Kontaktdaten des Admins für die Prefill-Demo (nur falls Felder das
|
|
// nutzen) — sonst leer.
|
|
$neededPrefillColumns = [];
|
|
foreach ($methods as $m) {
|
|
foreach ((array) ($m['form_fields'] ?? []) as $ff) {
|
|
$col = trim((string) ($ff['prefill_column'] ?? ''));
|
|
if ($col !== '' && ContactPrefillColumns::isValid($col)) {
|
|
$neededPrefillColumns[$col] = true;
|
|
}
|
|
}
|
|
}
|
|
$contactData = [];
|
|
if ($neededPrefillColumns !== []) {
|
|
try {
|
|
$contactRow = TaskCertDb::fetchOne(
|
|
'SELECT * FROM main_contact WHERE id = ? LIMIT 1',
|
|
'i',
|
|
[$auth->contactId()]
|
|
);
|
|
if (is_array($contactRow)) {
|
|
$contactData = $contactRow;
|
|
}
|
|
} catch (Throwable $e) {
|
|
$contactData = [];
|
|
}
|
|
}
|
|
|
|
// Stub-Assignment: offen, in ferner Zukunft fällig, gehört dem Admin. Damit
|
|
// rendert die Detailseite alle Methoden/Felder, ohne ein echtes Assignment.
|
|
$assignment = [
|
|
'id' => 0,
|
|
'task_id' => $taskId,
|
|
'status' => 'open',
|
|
'due_at' => '2099-12-31 23:59:59',
|
|
'main_contact_id' => $auth->contactId(),
|
|
];
|
|
|
|
// Variablen für das User-Template vorbelegen (überspringt dessen Lade-Guard).
|
|
$error = null;
|
|
$submissions = [];
|
|
$task_certificates_history = [];
|
|
$contact_data = $contactData;
|
|
$csrf_token = TaskCertCsrf::token();
|
|
$previewMode = true;
|
|
|
|
while (ob_get_level() > 0) {
|
|
ob_end_clean();
|
|
}
|
|
|
|
header('Content-Type: text/html; charset=utf-8');
|
|
|
|
// Host-Design-Tokens (--blue-accent, --border, --ff-primary, --tc-radius …)
|
|
// laden, damit die Vorschau exakt wie die echte, vom Host umrahmte Detailseite
|
|
// aussieht. Pfad entspricht dem Host-Wrapper (mysyde/frontend/frontend_mysyde.php).
|
|
$globalCssPath = '/layout/frontend/b2c/dist/css/global.css';
|
|
$globalCssAbs = ($_SERVER['DOCUMENT_ROOT'] ?? '') . $globalCssPath;
|
|
$globalCssHref = $globalCssPath;
|
|
if (is_file($globalCssAbs)) {
|
|
$globalCssHref .= '?time=' . filemtime($globalCssAbs);
|
|
}
|
|
?><!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Vorschau: <?php echo TaskCertView::e((string) ($task['title'] ?? 'Aufgabe')); ?></title>
|
|
<link rel="stylesheet" href="<?php echo TaskCertView::e($globalCssHref); ?>">
|
|
</head>
|
|
<body>
|
|
<?php require __DIR__ . '/../user/task_detail.php'; ?>
|
|
</body>
|
|
</html>
|
|
<?php
|
|
exit;
|