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>
This commit is contained in:
473
module/tasks/repo/TaskRuleRepository.php
Normal file
473
module/tasks/repo/TaskRuleRepository.php
Normal file
@@ -0,0 +1,473 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
class TaskRuleRepository
|
||||
{
|
||||
public function replaceTaskRules(int $taskId, array $dto, int $actorId): void
|
||||
{
|
||||
$this->replaceMethods($taskId, $dto['methods'] ?? []);
|
||||
$this->replaceTargetRules($taskId, $dto['target_rules'] ?? []);
|
||||
$this->replaceTargetOverrides($taskId, $dto['target_overrides'] ?? [], $actorId);
|
||||
$this->replaceReminderPolicy($taskId, $dto['reminder_policy'] ?? []);
|
||||
$this->replaceResponsibles($taskId, $dto['responsible_contact_ids'] ?? []);
|
||||
}
|
||||
|
||||
public function getTaskRuleBundle(int $taskId): array
|
||||
{
|
||||
return [
|
||||
'methods' => $this->getMethodsByTask($taskId, true),
|
||||
'target_rules' => $this->getTargetRulesByTask($taskId),
|
||||
'target_overrides' => $this->getTargetOverridesByTask($taskId),
|
||||
'reminder_policy' => $this->getReminderPolicyByTask($taskId),
|
||||
'responsible_contact_ids' => $this->getResponsibleContactIds($taskId),
|
||||
];
|
||||
}
|
||||
|
||||
public function findMethodById(int $methodId): ?array
|
||||
{
|
||||
return TaskCertDb::fetchOne('SELECT * FROM task_method WHERE id = ? AND active = 1', 'i', [$methodId]);
|
||||
}
|
||||
|
||||
public function getMethodsByTask(int $taskId, bool $includeInactive = false): array
|
||||
{
|
||||
$sql = 'SELECT * FROM task_method WHERE task_id = ?';
|
||||
if (!$includeInactive) {
|
||||
$sql .= ' AND active = 1';
|
||||
}
|
||||
$sql .= ' ORDER BY sort_order ASC, id ASC';
|
||||
|
||||
$methods = TaskCertDb::fetchAll($sql, 'i', [$taskId]);
|
||||
|
||||
foreach ($methods as &$method) {
|
||||
$methodId = (int) $method['id'];
|
||||
$method['settings'] = $this->decodeJson($method['settings_json'] ?? null);
|
||||
$method['knowledge_posts'] = $this->getKnowledgePostsForMethod($methodId);
|
||||
$method['form_fields'] = $this->getFormFieldsForMethod($methodId);
|
||||
$method['quiz_questions'] = $this->getQuizQuestionsWithOptions($methodId);
|
||||
unset($method['settings_json']);
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
|
||||
public function getTargetRulesByTask(int $taskId): array
|
||||
{
|
||||
return TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_target_rule WHERE task_id = ? ORDER BY id ASC',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
}
|
||||
|
||||
public function getTargetOverridesByTask(int $taskId): array
|
||||
{
|
||||
return TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_target_override WHERE task_id = ? ORDER BY id ASC',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
}
|
||||
|
||||
public function getReminderPolicyByTask(int $taskId): ?array
|
||||
{
|
||||
return TaskCertDb::fetchOne(
|
||||
'SELECT * FROM task_reminder_policy WHERE task_id = ? LIMIT 1',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
}
|
||||
|
||||
private function replaceMethods(int $taskId, array $methods): void
|
||||
{
|
||||
$existingRows = TaskCertDb::fetchAll(
|
||||
'SELECT id, method_type FROM task_method WHERE task_id = ?',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
$existingByType = [];
|
||||
foreach ($existingRows as $row) {
|
||||
$type = (string) ($row['method_type'] ?? '');
|
||||
$id = (int) ($row['id'] ?? 0);
|
||||
if ($type !== '' && $id > 0) {
|
||||
$existingByType[$type] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
$sort = 0;
|
||||
$seenTypes = [];
|
||||
foreach ($methods as $method) {
|
||||
$methodType = (string) ($method['method_type'] ?? '');
|
||||
if (!TaskCertConstants::isValidMethodType($methodType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$isRequired = (int) ($method['is_required'] ?? 1);
|
||||
$sortOrder = (int) ($method['sort_order'] ?? $sort);
|
||||
$settingsJson = json_encode($method['settings'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$active = (int) ($method['active'] ?? 1);
|
||||
$seenTypes[$methodType] = true;
|
||||
|
||||
if (isset($existingByType[$methodType])) {
|
||||
$methodId = (int) $existingByType[$methodType];
|
||||
TaskCertDb::execute(
|
||||
'UPDATE task_method
|
||||
SET is_required = ?, sort_order = ?, settings_json = ?, active = ?
|
||||
WHERE id = ?',
|
||||
'iisii',
|
||||
[$isRequired, $sortOrder, $settingsJson, $active, $methodId]
|
||||
);
|
||||
} else {
|
||||
$methodId = TaskCertDb::insert(
|
||||
'INSERT INTO task_method (task_id, method_type, is_required, sort_order, settings_json, active)
|
||||
VALUES (?, ?, ?, ?, ?, ?)',
|
||||
'isiisi',
|
||||
[$taskId, $methodType, $isRequired, $sortOrder, $settingsJson, $active]
|
||||
);
|
||||
}
|
||||
|
||||
$this->clearMethodChildren($methodId);
|
||||
|
||||
if ($methodType === 'knowledge_read') {
|
||||
$this->insertKnowledgePosts($methodId, $method['knowledge_posts'] ?? []);
|
||||
}
|
||||
|
||||
if ($methodType === 'form_submit') {
|
||||
$this->insertFormFields($methodId, $method['form_fields'] ?? []);
|
||||
}
|
||||
|
||||
if ($methodType === 'quiz') {
|
||||
$this->insertQuizQuestions($methodId, $method['quiz_questions'] ?? []);
|
||||
}
|
||||
|
||||
$sort++;
|
||||
}
|
||||
|
||||
foreach ($existingByType as $methodType => $methodId) {
|
||||
if (isset($seenTypes[$methodType])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TaskCertDb::execute(
|
||||
'UPDATE task_method
|
||||
SET active = 0, sort_order = ?
|
||||
WHERE id = ?',
|
||||
'ii',
|
||||
[$sort, (int) $methodId]
|
||||
);
|
||||
$sort++;
|
||||
}
|
||||
}
|
||||
|
||||
private function clearMethodChildren(int $methodId): void
|
||||
{
|
||||
TaskCertDb::execute('DELETE FROM task_method_knowledge_post WHERE method_id = ?', 'i', [$methodId]);
|
||||
TaskCertDb::execute('DELETE FROM task_form_field WHERE method_id = ?', 'i', [$methodId]);
|
||||
|
||||
$questionRows = TaskCertDb::fetchAll(
|
||||
'SELECT id FROM task_quiz_question WHERE method_id = ?',
|
||||
'i',
|
||||
[$methodId]
|
||||
);
|
||||
$questionIds = [];
|
||||
foreach ($questionRows as $row) {
|
||||
$questionId = (int) ($row['id'] ?? 0);
|
||||
if ($questionId > 0) {
|
||||
$questionIds[] = $questionId;
|
||||
}
|
||||
}
|
||||
|
||||
if ($questionIds !== []) {
|
||||
$placeholders = implode(',', array_fill(0, count($questionIds), '?'));
|
||||
TaskCertDb::execute(
|
||||
'DELETE FROM task_quiz_option WHERE question_id IN (' . $placeholders . ')',
|
||||
str_repeat('i', count($questionIds)),
|
||||
$questionIds
|
||||
);
|
||||
}
|
||||
|
||||
TaskCertDb::execute('DELETE FROM task_quiz_question WHERE method_id = ?', 'i', [$methodId]);
|
||||
}
|
||||
|
||||
private function replaceTargetRules(int $taskId, array $targetRules): void
|
||||
{
|
||||
TaskCertDb::execute('DELETE FROM task_target_rule WHERE task_id = ?', 'i', [$taskId]);
|
||||
|
||||
foreach ($targetRules as $rule) {
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_target_rule (task_id, main_mandant_id, main_department_id, main_role_id, active)
|
||||
VALUES (?, ?, ?, ?, ?)',
|
||||
'iiiii',
|
||||
[
|
||||
$taskId,
|
||||
(int) ($rule['main_mandant_id'] ?? 0) ?: null,
|
||||
(int) ($rule['main_department_id'] ?? 0) ?: null,
|
||||
(int) ($rule['main_role_id'] ?? 0) ?: null,
|
||||
(int) ($rule['active'] ?? 1),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function replaceTargetOverrides(int $taskId, array $overrides, int $actorId): void
|
||||
{
|
||||
TaskCertDb::execute('DELETE FROM task_target_override WHERE task_id = ?', 'i', [$taskId]);
|
||||
|
||||
foreach ($overrides as $override) {
|
||||
$type = (string) ($override['override_type'] ?? '');
|
||||
$contactId = (int) ($override['main_contact_id'] ?? 0);
|
||||
|
||||
if (!in_array($type, ['include', 'exclude'], true) || $contactId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_target_override (task_id, main_contact_id, override_type, reason, created_by)
|
||||
VALUES (?, ?, ?, ?, ?)',
|
||||
'iissi',
|
||||
[
|
||||
$taskId,
|
||||
$contactId,
|
||||
$type,
|
||||
(string) ($override['reason'] ?? ''),
|
||||
$actorId,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function replaceReminderPolicy(int $taskId, array $policy): void
|
||||
{
|
||||
TaskCertDb::execute('DELETE FROM task_reminder_policy WHERE task_id = ?', 'i', [$taskId]);
|
||||
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_reminder_policy (task_id, base_mode, first_escalation_days, step_days, max_level, grace_days, active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
'isiiiii',
|
||||
[
|
||||
$taskId,
|
||||
'due_date',
|
||||
(int) ($policy['first_escalation_days'] ?? 0),
|
||||
max(1, (int) ($policy['step_days'] ?? 7)),
|
||||
max(1, (int) ($policy['max_level'] ?? 3)),
|
||||
max(0, (int) ($policy['grace_days'] ?? 7)),
|
||||
(int) ($policy['active'] ?? 1),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function insertKnowledgePosts(int $methodId, array $knowledgePosts): void
|
||||
{
|
||||
$sortOrder = 0;
|
||||
foreach ($knowledgePosts as $item) {
|
||||
$postId = is_array($item) ? (int) ($item['knowledge_post_id'] ?? 0) : (int) $item;
|
||||
if ($postId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$required = is_array($item) ? (int) ($item['required'] ?? 1) : 1;
|
||||
$sort = is_array($item) ? (int) ($item['sort_order'] ?? $sortOrder) : $sortOrder;
|
||||
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_method_knowledge_post (method_id, knowledge_post_id, required, sort_order)
|
||||
VALUES (?, ?, ?, ?)',
|
||||
'iiii',
|
||||
[$methodId, $postId, $required, $sort]
|
||||
);
|
||||
|
||||
$sortOrder++;
|
||||
}
|
||||
}
|
||||
|
||||
private function insertFormFields(int $methodId, array $fields): void
|
||||
{
|
||||
$sortOrder = 0;
|
||||
foreach ($fields as $field) {
|
||||
if (!is_array($field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldKey = trim((string) ($field['field_key'] ?? ''));
|
||||
$label = trim((string) ($field['label'] ?? ''));
|
||||
$fieldType = (string) ($field['field_type'] ?? 'text');
|
||||
|
||||
if ($fieldKey === '' || $label === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TaskCertConstants::isValidFieldType($fieldType)) {
|
||||
$fieldType = 'text';
|
||||
}
|
||||
|
||||
$prefillColumn = ContactPrefillColumns::sanitize((string) ($field['prefill_column'] ?? ''));
|
||||
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_form_field (method_id, field_key, label, field_type, is_required, options_json, placeholder, prefill_column, sort_order, active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
'isssisssii',
|
||||
[
|
||||
$methodId,
|
||||
$fieldKey,
|
||||
$label,
|
||||
$fieldType,
|
||||
(int) ($field['is_required'] ?? 0),
|
||||
json_encode($field['options'] ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
||||
(string) ($field['placeholder'] ?? ''),
|
||||
$prefillColumn,
|
||||
(int) ($field['sort_order'] ?? $sortOrder),
|
||||
(int) ($field['active'] ?? 1),
|
||||
]
|
||||
);
|
||||
|
||||
$sortOrder++;
|
||||
}
|
||||
}
|
||||
|
||||
private function insertQuizQuestions(int $methodId, array $questions): void
|
||||
{
|
||||
$questionSort = 0;
|
||||
foreach ($questions as $question) {
|
||||
if (!is_array($question)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$questionText = trim((string) ($question['question_text'] ?? ''));
|
||||
if ($questionText === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$questionId = TaskCertDb::insert(
|
||||
'INSERT INTO task_quiz_question (method_id, question_text, sort_order, active)
|
||||
VALUES (?, ?, ?, ?)',
|
||||
'isii',
|
||||
[
|
||||
$methodId,
|
||||
$questionText,
|
||||
(int) ($question['sort_order'] ?? $questionSort),
|
||||
(int) ($question['active'] ?? 1),
|
||||
]
|
||||
);
|
||||
|
||||
$options = is_array($question['options'] ?? null) ? $question['options'] : [];
|
||||
$optionSort = 0;
|
||||
foreach ($options as $option) {
|
||||
if (!is_array($option)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$optionText = trim((string) ($option['option_text'] ?? ''));
|
||||
if ($optionText === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_quiz_option (question_id, option_text, is_correct, sort_order)
|
||||
VALUES (?, ?, ?, ?)',
|
||||
'isii',
|
||||
[
|
||||
$questionId,
|
||||
$optionText,
|
||||
(int) ($option['is_correct'] ?? 0),
|
||||
(int) ($option['sort_order'] ?? $optionSort),
|
||||
]
|
||||
);
|
||||
|
||||
$optionSort++;
|
||||
}
|
||||
|
||||
$questionSort++;
|
||||
}
|
||||
}
|
||||
|
||||
private function getKnowledgePostsForMethod(int $methodId): array
|
||||
{
|
||||
return TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_method_knowledge_post WHERE method_id = ? ORDER BY sort_order ASC, id ASC',
|
||||
'i',
|
||||
[$methodId]
|
||||
);
|
||||
}
|
||||
|
||||
private function getFormFieldsForMethod(int $methodId): array
|
||||
{
|
||||
$rows = TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_form_field WHERE method_id = ? ORDER BY sort_order ASC, id ASC',
|
||||
'i',
|
||||
[$methodId]
|
||||
);
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
$row['options'] = $this->decodeJson($row['options_json'] ?? null);
|
||||
unset($row['options_json']);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function getQuizQuestionsWithOptions(int $methodId): array
|
||||
{
|
||||
$questions = TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_quiz_question WHERE method_id = ? ORDER BY sort_order ASC, id ASC',
|
||||
'i',
|
||||
[$methodId]
|
||||
);
|
||||
|
||||
foreach ($questions as &$question) {
|
||||
$question['options'] = TaskCertDb::fetchAll(
|
||||
'SELECT * FROM task_quiz_option WHERE question_id = ? ORDER BY sort_order ASC, id ASC',
|
||||
'i',
|
||||
[(int) $question['id']]
|
||||
);
|
||||
}
|
||||
|
||||
return $questions;
|
||||
}
|
||||
|
||||
private function decodeJson(?string $json): array
|
||||
{
|
||||
if ($json === null || trim($json) === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$decoded = json_decode($json, true);
|
||||
return is_array($decoded) ? $decoded : [];
|
||||
}
|
||||
|
||||
public function getResponsibleContactIds(int $taskId): array
|
||||
{
|
||||
$rows = TaskCertDb::fetchAll(
|
||||
'SELECT main_contact_id FROM task_responsible WHERE task_id = ? ORDER BY id ASC',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
|
||||
return array_map(static fn(array $row): int => (int) $row['main_contact_id'], $rows);
|
||||
}
|
||||
|
||||
public function getResponsiblesWithContactData(int $taskId): array
|
||||
{
|
||||
return TaskCertDb::fetchAll(
|
||||
'SELECT r.main_contact_id, c.name, c.email
|
||||
FROM task_responsible r
|
||||
INNER JOIN main_contact c ON c.id = r.main_contact_id
|
||||
WHERE r.task_id = ?
|
||||
ORDER BY c.name ASC',
|
||||
'i',
|
||||
[$taskId]
|
||||
);
|
||||
}
|
||||
|
||||
private function replaceResponsibles(int $taskId, array $contactIds): void
|
||||
{
|
||||
TaskCertDb::execute('DELETE FROM task_responsible WHERE task_id = ?', 'i', [$taskId]);
|
||||
|
||||
$contactIds = array_values(array_unique(array_filter(array_map('intval', $contactIds), static fn(int $id): bool => $id > 0)));
|
||||
|
||||
foreach ($contactIds as $contactId) {
|
||||
TaskCertDb::insert(
|
||||
'INSERT INTO task_responsible (task_id, main_contact_id) VALUES (?, ?)',
|
||||
'ii',
|
||||
[$taskId, $contactId]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user