Files
awo-hamburg-intranet/module/tasks/repo/TaskCertificateRepository.php
Moritz Weinmann 743476f64a Module tasks + knowledgecenter_update aus Kundenprojekt übernehmen (bereinigt)
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>
2026-06-22 09:20:02 +02:00

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]
);
}
}