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>
220 lines
7.0 KiB
PHP
220 lines
7.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
class TaskCertificateRepository
|
|
{
|
|
public function create(array $data): int
|
|
{
|
|
return TaskCertDb::insert(
|
|
'INSERT INTO task_certificate (
|
|
task_id,
|
|
assignment_id,
|
|
submission_id,
|
|
main_contact_id,
|
|
certificate_code,
|
|
valid_from,
|
|
valid_until,
|
|
status
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
'iiiissss',
|
|
[
|
|
$data['task_id'],
|
|
$data['assignment_id'],
|
|
$data['submission_id'],
|
|
$data['main_contact_id'],
|
|
$data['certificate_code'],
|
|
$data['valid_from'],
|
|
$data['valid_until'],
|
|
$data['status'],
|
|
]
|
|
);
|
|
}
|
|
|
|
public function findByAssignmentId(int $assignmentId): ?array
|
|
{
|
|
return TaskCertDb::fetchOne(
|
|
'SELECT * FROM task_certificate WHERE assignment_id = ? LIMIT 1',
|
|
'i',
|
|
[$assignmentId]
|
|
);
|
|
}
|
|
|
|
public function listAssignmentIdsWithCertificates(array $assignmentIds): array
|
|
{
|
|
$assignmentIds = array_values(array_unique(array_map('intval', $assignmentIds)));
|
|
$assignmentIds = array_values(array_filter($assignmentIds, static function (int $assignmentId): bool {
|
|
return $assignmentId > 0;
|
|
}));
|
|
|
|
if ($assignmentIds === []) {
|
|
return [];
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($assignmentIds), '?'));
|
|
$rows = TaskCertDb::fetchAll(
|
|
'SELECT DISTINCT assignment_id
|
|
FROM task_certificate
|
|
WHERE assignment_id IN (' . $placeholders . ')',
|
|
str_repeat('i', count($assignmentIds)),
|
|
$assignmentIds
|
|
);
|
|
|
|
$result = [];
|
|
foreach ($rows as $row) {
|
|
$assignmentId = (int) ($row['assignment_id'] ?? 0);
|
|
if ($assignmentId <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$result[] = $assignmentId;
|
|
}
|
|
|
|
$result = array_values(array_unique($result));
|
|
sort($result);
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function listForUser(int $contactId): array
|
|
{
|
|
return TaskCertDb::fetchAll(
|
|
'SELECT c.*, d.title AS task_title
|
|
FROM task_certificate c
|
|
INNER JOIN task_definition d ON d.id = c.task_id
|
|
WHERE c.main_contact_id = ?
|
|
ORDER BY c.issued_at DESC',
|
|
'i',
|
|
[$contactId]
|
|
);
|
|
}
|
|
|
|
public function listForUserTask(int $contactId, int $taskId): array
|
|
{
|
|
return TaskCertDb::fetchAll(
|
|
'SELECT c.*, a.cycle_key
|
|
FROM task_certificate c
|
|
LEFT JOIN task_assignment a ON a.id = c.assignment_id
|
|
WHERE c.main_contact_id = ?
|
|
AND c.task_id = ?
|
|
ORDER BY c.issued_at DESC, c.id DESC',
|
|
'ii',
|
|
[$contactId, $taskId]
|
|
);
|
|
}
|
|
|
|
public function summarizeForUserTasks(int $contactId, array $taskIds): array
|
|
{
|
|
$taskIds = array_values(array_unique(array_map('intval', $taskIds)));
|
|
$taskIds = array_values(array_filter($taskIds, static function (int $taskId): bool {
|
|
return $taskId > 0;
|
|
}));
|
|
|
|
if ($taskIds === []) {
|
|
return [];
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($taskIds), '?'));
|
|
$sql = 'SELECT
|
|
c.task_id,
|
|
COUNT(*) AS total_count,
|
|
SUM(CASE WHEN c.status = "valid" THEN 1 ELSE 0 END) AS valid_count,
|
|
MAX(c.issued_at) AS latest_issued_at,
|
|
(
|
|
SELECT c2.valid_until
|
|
FROM task_certificate c2
|
|
WHERE c2.main_contact_id = c.main_contact_id
|
|
AND c2.task_id = c.task_id
|
|
ORDER BY c2.issued_at DESC, c2.id DESC
|
|
LIMIT 1
|
|
) AS latest_valid_until
|
|
FROM task_certificate c
|
|
WHERE c.main_contact_id = ?
|
|
AND c.task_id IN (' . $placeholders . ')
|
|
GROUP BY c.task_id';
|
|
|
|
$types = 'i' . str_repeat('i', count($taskIds));
|
|
$params = array_merge([$contactId], $taskIds);
|
|
$rows = TaskCertDb::fetchAll($sql, $types, $params);
|
|
|
|
$summaryByTask = [];
|
|
foreach ($rows as $row) {
|
|
$taskId = (int) ($row['task_id'] ?? 0);
|
|
if ($taskId <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$summaryByTask[$taskId] = [
|
|
'task_id' => $taskId,
|
|
'total_count' => (int) ($row['total_count'] ?? 0),
|
|
'valid_count' => (int) ($row['valid_count'] ?? 0),
|
|
'latest_issued_at' => (string) ($row['latest_issued_at'] ?? ''),
|
|
'latest_valid_until' => (string) ($row['latest_valid_until'] ?? ''),
|
|
];
|
|
}
|
|
|
|
return $summaryByTask;
|
|
}
|
|
|
|
public function deleteByAssignmentIds(array $assignmentIds): int
|
|
{
|
|
$assignmentIds = array_values(array_unique(array_map('intval', $assignmentIds)));
|
|
$assignmentIds = array_values(array_filter($assignmentIds, static function (int $assignmentId): bool {
|
|
return $assignmentId > 0;
|
|
}));
|
|
|
|
if ($assignmentIds === []) {
|
|
return 0;
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($assignmentIds), '?'));
|
|
$types = str_repeat('i', count($assignmentIds));
|
|
|
|
return TaskCertDb::execute(
|
|
'DELETE FROM task_certificate WHERE assignment_id IN (' . $placeholders . ')',
|
|
$types,
|
|
$assignmentIds
|
|
);
|
|
}
|
|
|
|
public function revokeByAssignmentIds(array $assignmentIds, int $revokedBy, string $reason): int
|
|
{
|
|
$assignmentIds = array_values(array_unique(array_map('intval', $assignmentIds)));
|
|
$assignmentIds = array_values(array_filter($assignmentIds, static function (int $assignmentId): bool {
|
|
return $assignmentId > 0;
|
|
}));
|
|
|
|
if ($assignmentIds === []) {
|
|
return 0;
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($assignmentIds), '?'));
|
|
$types = 'is' . str_repeat('i', count($assignmentIds));
|
|
$params = array_merge([$revokedBy, $reason], $assignmentIds);
|
|
|
|
return TaskCertDb::execute(
|
|
'UPDATE task_certificate
|
|
SET status = "revoked",
|
|
revoked_at = COALESCE(revoked_at, NOW()),
|
|
revoked_by = ?,
|
|
revoke_reason = ?
|
|
WHERE assignment_id IN (' . $placeholders . ')
|
|
AND status <> "revoked"',
|
|
$types,
|
|
$params
|
|
);
|
|
}
|
|
|
|
public function markExpiredByDate(string $now): int
|
|
{
|
|
return TaskCertDb::execute(
|
|
'UPDATE task_certificate
|
|
SET status = "expired"
|
|
WHERE status = "valid"
|
|
AND valid_until IS NOT NULL
|
|
AND valid_until < ?',
|
|
's',
|
|
[$now]
|
|
);
|
|
}
|
|
}
|