{
"tool_response": {
"type": "update",
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ConfigController.php",
"content": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse UseCases\\Config\\ManageConfigUseCase;\n\nclass ConfigController extends Controller\n{\n private ManageConfigUseCase $configUseCase;\n\n private const TYPES = ['author_profile', 'structure', 'organization', 'contract', 'rule', 'system_prompt'];\n private const TYPE_LABELS = [\n 'author_profile' => 'Autorenprofil',\n 'structure' => 'Struktur',\n 'organization' => 'Organisation',\n 'contract' => 'Contract',\n 'rule' => 'Regel',\n 'system_prompt' => 'System-Prompt',\n ];\n\n public function __construct(?ManageConfigUseCase $configUseCase = null)\n {\n $this->configUseCase = $configUseCase ?? new ManageConfigUseCase();\n }\n\n public function index(): void\n {\n $typeFilter = $this->getString('type');\n $statusFilter = $this->getString('status');\n\n $this->view('config.index', [\n 'title' => 'Content-Konfiguration',\n 'configs' => array_map(fn ($dto) => (array) $dto, $this->configUseCase->getAll($typeFilter, $statusFilter)),\n 'stats' => $this->configUseCase->getStatistics(),\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'currentType' => $typeFilter,\n 'currentStatus' => $statusFilter,\n ]);\n }\n\n public function configNew(): void\n {\n $this->view('config.form', [\n 'title' => 'Neue Konfiguration',\n 'config' => null,\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'parents' => $this->configUseCase->getParentOptions(),\n 'isEdit' => false,\n ]);\n }\n\n public function store(): void\n {\n $this->requireCsrf();\n\n $result = $this->configUseCase->create(\n type: $_POST['type'] ?? '',\n name: $_POST['name'] ?? '',\n slug: $_POST['slug'] ?? '',\n description: $_POST['description'] ?? null,\n content: $_POST['content'] ?? '{}',\n version: $_POST['version'] ?? '1.0',\n status: $_POST['status'] ?? 'draft',\n parentId: !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null\n );\n\n if (!$result->success) {\n $_SESSION['error'] = $result->message;\n header('Location: \/config\/new');\n exit;\n }\n\n $_SESSION['success'] = $result->message;\n header('Location: \/config\/' . $result->id);\n exit;\n }\n\n public function show(string $id): void\n {\n $config = $this->configUseCase->getById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n $this->view('config.show', [\n 'title' => $config->name,\n 'config' => (array) $config,\n 'children' => $this->configUseCase->getChildren((int) $id),\n 'history' => $this->configUseCase->getHistory((int) $id),\n 'typeLabels' => self::TYPE_LABELS,\n ]);\n }\n\n public function edit(string $id): void\n {\n $config = $this->configUseCase->getById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n $this->view('config.form', [\n 'title' => 'Bearbeiten: ' . $config->name,\n 'config' => (array) $config,\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'parents' => $this->configUseCase->getParentOptions((int) $id),\n 'isEdit' => true,\n ]);\n }\n\n public function update(string $id): void\n {\n $this->requireCsrf();\n\n $result = $this->configUseCase->update(\n id: (int) $id,\n name: $_POST['name'] ?? '',\n slug: $_POST['slug'] ?? '',\n description: $_POST['description'] ?? null,\n content: $_POST['content'] ?? '{}',\n newVersion: $_POST['new_version'] ?? '',\n changeDescription: $_POST['change_description'] ?? '',\n status: $_POST['status'] ?? 'draft',\n parentId: !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null\n );\n\n if (!$result->success) {\n $_SESSION['error'] = $result->message;\n header('Location: \/config\/' . $id . '\/edit');\n exit;\n }\n\n $_SESSION['success'] = $result->message;\n header('Location: \/config\/' . $id);\n exit;\n }\n\n public function delete(string $id): void\n {\n $this->requireCsrf();\n\n $result = $this->configUseCase->delete((int) $id);\n\n if (!$result->success) {\n $_SESSION['error'] = $result->message;\n header('Location: \/config\/' . $id);\n exit;\n }\n\n $_SESSION['success'] = $result->message;\n header('Location: \/config');\n exit;\n }\n}\n",
"structuredPatch": [
{
"oldStart": 3,
"oldLines": 11,
"newStart": 3,
"newLines": 11,
"lines": [
" namespace Controller;",
" ",
" use Framework\\Controller;",
"-use Infrastructure\\Persistence\\ContentConfigRepository;",
"+use UseCases\\Config\\ManageConfigUseCase;",
" ",
" class ConfigController extends Controller",
" {",
"- private ContentConfigRepository $configRepo;",
"+ private ManageConfigUseCase $configUseCase;",
" ",
" private const TYPES = ['author_profile', 'structure', 'organization', 'contract', 'rule', 'system_prompt'];",
" private const TYPE_LABELS = ["
]
},
{
"oldStart": 19,
"oldLines": 9,
"newStart": 19,
"newLines": 9,
"lines": [
" 'system_prompt' => 'System-Prompt',",
" ];",
" ",
"- public function __construct(?ContentConfigRepository $configRepo = null)",
"+ public function __construct(?ManageConfigUseCase $configUseCase = null)",
" {",
"- $this->configRepo = $configRepo ?? new ContentConfigRepository();",
"+ $this->configUseCase = $configUseCase ?? new ManageConfigUseCase();",
" }",
" ",
" public function index(): void"
]
},
{
"oldStart": 29,
"oldLines": 13,
"newStart": 29,
"newLines": 10,
"lines": [
" $typeFilter = $this->getString('type');",
" $statusFilter = $this->getString('status');",
" ",
"- $validType = in_array($typeFilter, self::TYPES, true) ? $typeFilter : null;",
"- $validStatus = in_array($statusFilter, ['draft', 'active', 'deprecated'], true) ? $statusFilter : null;",
"-",
" $this->view('config.index', [",
" 'title' => 'Content-Konfiguration',",
"- 'configs' => $this->configRepo->findAll($validType, $validStatus),",
"- 'stats' => $this->configRepo->getStatistics(),",
"+ 'configs' => array_map(fn ($dto) => (array) $dto, $this->configUseCase->getAll($typeFilter, $statusFilter)),",
"+ 'stats' => $this->configUseCase->getStatistics(),",
" 'types' => self::TYPES,",
" 'typeLabels' => self::TYPE_LABELS,",
" 'currentType' => $typeFilter,"
]
},
{
"oldStart": 50,
"oldLines": 7,
"newStart": 47,
"newLines": 7,
"lines": [
" 'config' => null,",
" 'types' => self::TYPES,",
" 'typeLabels' => self::TYPE_LABELS,",
"- 'parents' => $this->configRepo->getParentOptions(),",
"+ 'parents' => $this->configUseCase->getParentOptions(),",
" 'isEdit' => false,",
" ]);",
" }"
]
},
{
"oldStart": 59,
"oldLines": 73,
"newStart": 56,
"newLines": 57,
"lines": [
" {",
" $this->requireCsrf();",
" ",
"- $type = $_POST['type'] ?? '';",
"- $name = trim($_POST['name'] ?? '');",
"- $slug = trim($_POST['slug'] ?? '');",
"- $description = trim($_POST['description'] ?? '');",
"- $content = $_POST['content'] ?? '{}';",
"- $version = trim($_POST['version'] ?? '1.0');",
"- $status = $_POST['status'] ?? 'draft';",
"- $parentId = !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null;",
"+ $result = $this->configUseCase->create(",
"+ type: $_POST['type'] ?? '',",
"+ name: $_POST['name'] ?? '',",
"+ slug: $_POST['slug'] ?? '',",
"+ description: $_POST['description'] ?? null,",
"+ content: $_POST['content'] ?? '{}',",
"+ version: $_POST['version'] ?? '1.0',",
"+ status: $_POST['status'] ?? 'draft',",
"+ parentId: !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null",
"+ );",
" ",
"- if (!in_array($type, self::TYPES, true) || $name === '' || $slug === '') {",
"- $_SESSION['error'] = 'Typ, Name und Slug sind erforderlich.';",
"+ if (!$result->success) {",
"+ $_SESSION['error'] = $result->message;",
" header('Location: \/config\/new');",
" exit;",
" }",
" ",
"- $decoded = json_decode($content, true);",
"- if ($decoded === null && $content !== 'null') {",
"- $_SESSION['error'] = 'Ungültiges JSON-Format.';",
"- header('Location: \/config\/new');",
"- exit;",
"- }",
"-",
"- $id = $this->configRepo->create(",
"- $type,",
"- $name,",
"- $slug,",
"- $description !== '' ? $description : null,",
"- $content,",
"- $version,",
"- $status,",
"- $parentId",
"- );",
"-",
"- $_SESSION['success'] = 'Konfiguration erfolgreich erstellt.';",
"- header('Location: \/config\/' . $id);",
"+ $_SESSION['success'] = $result->message;",
"+ header('Location: \/config\/' . $result->id);",
" exit;",
" }",
" ",
" public function show(string $id): void",
" {",
"- $config = $this->configRepo->findById((int) $id);",
"+ $config = $this->configUseCase->getById((int) $id);",
" if ($config === null) {",
" $this->notFound('Konfiguration nicht gefunden');",
" }",
" ",
" $this->view('config.show', [",
"- 'title' => $config['name'],",
"- 'config' => $config,",
"- 'children' => $this->configRepo->getChildren((int) $id),",
"- 'history' => $this->configRepo->getHistory((int) $id),",
"+ 'title' => $config->name,",
"+ 'config' => (array) $config,",
"+ 'children' => $this->configUseCase->getChildren((int) $id),",
"+ 'history' => $this->configUseCase->getHistory((int) $id),",
" 'typeLabels' => self::TYPE_LABELS,",
" ]);",
" }",
" ",
" public function edit(string $id): void",
" {",
"- $config = $this->configRepo->findById((int) $id);",
"+ $config = $this->configUseCase->getById((int) $id);",
" if ($config === null) {",
" $this->notFound('Konfiguration nicht gefunden');",
" }",
" ",
" $this->view('config.form', [",
"- 'title' => 'Bearbeiten: ' . $config['name'],",
"- 'config' => $config,",
"+ 'title' => 'Bearbeiten: ' . $config->name,",
"+ 'config' => (array) $config,",
" 'types' => self::TYPES,",
" 'typeLabels' => self::TYPE_LABELS,",
"- 'parents' => $this->configRepo->getParentOptions((int) $id),",
"+ 'parents' => $this->configUseCase->getParentOptions((int) $id),",
" 'isEdit' => true,",
" ]);",
" }"
]
},
{
"oldStart": 134,
"oldLines": 53,
"newStart": 115,
"newLines": 25,
"lines": [
" {",
" $this->requireCsrf();",
" ",
"- $config = $this->configRepo->findById((int) $id);",
"- if ($config === null) {",
"- $this->notFound('Konfiguration nicht gefunden');",
"- }",
"+ $result = $this->configUseCase->update(",
"+ id: (int) $id,",
"+ name: $_POST['name'] ?? '',",
"+ slug: $_POST['slug'] ?? '',",
"+ description: $_POST['description'] ?? null,",
"+ content: $_POST['content'] ?? '{}',",
"+ newVersion: $_POST['new_version'] ?? '',",
"+ changeDescription: $_POST['change_description'] ?? '',",
"+ status: $_POST['status'] ?? 'draft',",
"+ parentId: !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null",
"+ );",
" ",
"- $name = trim($_POST['name'] ?? '');",
"- $slug = trim($_POST['slug'] ?? '');",
"- $description = trim($_POST['description'] ?? '');",
"- $content = $_POST['content'] ?? '{}';",
"- $newVersion = trim($_POST['new_version'] ?? '');",
"- $changeDescription = trim($_POST['change_description'] ?? '');",
"- $status = $_POST['status'] ?? $config['status'];",
"- $parentId = !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null;",
"-",
"- if ($name === '' || $slug === '' || $newVersion === '') {",
"- $_SESSION['error'] = 'Name, Slug und neue Version sind erforderlich.';",
"+ if (!$result->success) {",
"+ $_SESSION['error'] = $result->message;",
" header('Location: \/config\/' . $id . '\/edit');",
" exit;",
" }",
" ",
"- $decoded = json_decode($content, true);",
"- if ($decoded === null && $content !== 'null') {",
"- $_SESSION['error'] = 'Ungültiges JSON-Format.';",
"- header('Location: \/config\/' . $id . '\/edit');",
"- exit;",
"- }",
"-",
"- $this->configRepo->saveHistory(",
"- (int) $id,",
"- $config['content'],",
"- $config['version'],",
"- 'web-ui',",
"- $changeDescription !== '' ? $changeDescription : 'Update auf Version ' . $newVersion",
"- );",
"-",
"- $this->configRepo->update(",
"- (int) $id,",
"- $name,",
"- $slug,",
"- $description !== '' ? $description : null,",
"- $content,",
"- $newVersion,",
"- $status,",
"- $parentId",
"- );",
"-",
"- $_SESSION['success'] = 'Konfiguration auf Version ' . $newVersion . ' aktualisiert.';",
"+ $_SESSION['success'] = $result->message;",
" header('Location: \/config\/' . $id);",
" exit;",
" }"
]
},
{
"oldStart": 189,
"oldLines": 21,
"newStart": 142,
"newLines": 15,
"lines": [
" {",
" $this->requireCsrf();",
" ",
"- $config = $this->configRepo->findById((int) $id);",
"- if ($config === null) {",
"- $this->notFound('Konfiguration nicht gefunden');",
"- }",
"+ $result = $this->configUseCase->delete((int) $id);",
" ",
"- if ($this->configRepo->countChildren((int) $id) > 0) {",
"- $_SESSION['error'] = 'Kann nicht gelöscht werden: Es existieren verknüpfte Einträge.';",
"+ if (!$result->success) {",
"+ $_SESSION['error'] = $result->message;",
" header('Location: \/config\/' . $id);",
" exit;",
" }",
" ",
"- $this->configRepo->deleteHistory((int) $id);",
"- $this->configRepo->delete((int) $id);",
"-",
"- $_SESSION['success'] = 'Konfiguration gelöscht.';",
"+ $_SESSION['success'] = $result->message;",
" header('Location: \/config');",
" exit;",
" }"
]
}
],
"originalFile": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse Infrastructure\\Persistence\\ContentConfigRepository;\n\nclass ConfigController extends Controller\n{\n private ContentConfigRepository $configRepo;\n\n private const TYPES = ['author_profile', 'structure', 'organization', 'contract', 'rule', 'system_prompt'];\n private const TYPE_LABELS = [\n 'author_profile' => 'Autorenprofil',\n 'structure' => 'Struktur',\n 'organization' => 'Organisation',\n 'contract' => 'Contract',\n 'rule' => 'Regel',\n 'system_prompt' => 'System-Prompt',\n ];\n\n public function __construct(?ContentConfigRepository $configRepo = null)\n {\n $this->configRepo = $configRepo ?? new ContentConfigRepository();\n }\n\n public function index(): void\n {\n $typeFilter = $this->getString('type');\n $statusFilter = $this->getString('status');\n\n $validType = in_array($typeFilter, self::TYPES, true) ? $typeFilter : null;\n $validStatus = in_array($statusFilter, ['draft', 'active', 'deprecated'], true) ? $statusFilter : null;\n\n $this->view('config.index', [\n 'title' => 'Content-Konfiguration',\n 'configs' => $this->configRepo->findAll($validType, $validStatus),\n 'stats' => $this->configRepo->getStatistics(),\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'currentType' => $typeFilter,\n 'currentStatus' => $statusFilter,\n ]);\n }\n\n public function configNew(): void\n {\n $this->view('config.form', [\n 'title' => 'Neue Konfiguration',\n 'config' => null,\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'parents' => $this->configRepo->getParentOptions(),\n 'isEdit' => false,\n ]);\n }\n\n public function store(): void\n {\n $this->requireCsrf();\n\n $type = $_POST['type'] ?? '';\n $name = trim($_POST['name'] ?? '');\n $slug = trim($_POST['slug'] ?? '');\n $description = trim($_POST['description'] ?? '');\n $content = $_POST['content'] ?? '{}';\n $version = trim($_POST['version'] ?? '1.0');\n $status = $_POST['status'] ?? 'draft';\n $parentId = !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null;\n\n if (!in_array($type, self::TYPES, true) || $name === '' || $slug === '') {\n $_SESSION['error'] = 'Typ, Name und Slug sind erforderlich.';\n header('Location: \/config\/new');\n exit;\n }\n\n $decoded = json_decode($content, true);\n if ($decoded === null && $content !== 'null') {\n $_SESSION['error'] = 'Ungültiges JSON-Format.';\n header('Location: \/config\/new');\n exit;\n }\n\n $id = $this->configRepo->create(\n $type,\n $name,\n $slug,\n $description !== '' ? $description : null,\n $content,\n $version,\n $status,\n $parentId\n );\n\n $_SESSION['success'] = 'Konfiguration erfolgreich erstellt.';\n header('Location: \/config\/' . $id);\n exit;\n }\n\n public function show(string $id): void\n {\n $config = $this->configRepo->findById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n $this->view('config.show', [\n 'title' => $config['name'],\n 'config' => $config,\n 'children' => $this->configRepo->getChildren((int) $id),\n 'history' => $this->configRepo->getHistory((int) $id),\n 'typeLabels' => self::TYPE_LABELS,\n ]);\n }\n\n public function edit(string $id): void\n {\n $config = $this->configRepo->findById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n $this->view('config.form', [\n 'title' => 'Bearbeiten: ' . $config['name'],\n 'config' => $config,\n 'types' => self::TYPES,\n 'typeLabels' => self::TYPE_LABELS,\n 'parents' => $this->configRepo->getParentOptions((int) $id),\n 'isEdit' => true,\n ]);\n }\n\n public function update(string $id): void\n {\n $this->requireCsrf();\n\n $config = $this->configRepo->findById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n $name = trim($_POST['name'] ?? '');\n $slug = trim($_POST['slug'] ?? '');\n $description = trim($_POST['description'] ?? '');\n $content = $_POST['content'] ?? '{}';\n $newVersion = trim($_POST['new_version'] ?? '');\n $changeDescription = trim($_POST['change_description'] ?? '');\n $status = $_POST['status'] ?? $config['status'];\n $parentId = !empty($_POST['parent_id']) ? (int) $_POST['parent_id'] : null;\n\n if ($name === '' || $slug === '' || $newVersion === '') {\n $_SESSION['error'] = 'Name, Slug und neue Version sind erforderlich.';\n header('Location: \/config\/' . $id . '\/edit');\n exit;\n }\n\n $decoded = json_decode($content, true);\n if ($decoded === null && $content !== 'null') {\n $_SESSION['error'] = 'Ungültiges JSON-Format.';\n header('Location: \/config\/' . $id . '\/edit');\n exit;\n }\n\n $this->configRepo->saveHistory(\n (int) $id,\n $config['content'],\n $config['version'],\n 'web-ui',\n $changeDescription !== '' ? $changeDescription : 'Update auf Version ' . $newVersion\n );\n\n $this->configRepo->update(\n (int) $id,\n $name,\n $slug,\n $description !== '' ? $description : null,\n $content,\n $newVersion,\n $status,\n $parentId\n );\n\n $_SESSION['success'] = 'Konfiguration auf Version ' . $newVersion . ' aktualisiert.';\n header('Location: \/config\/' . $id);\n exit;\n }\n\n public function delete(string $id): void\n {\n $this->requireCsrf();\n\n $config = $this->configRepo->findById((int) $id);\n if ($config === null) {\n $this->notFound('Konfiguration nicht gefunden');\n }\n\n if ($this->configRepo->countChildren((int) $id) > 0) {\n $_SESSION['error'] = 'Kann nicht gelöscht werden: Es existieren verknüpfte Einträge.';\n header('Location: \/config\/' . $id);\n exit;\n }\n\n $this->configRepo->deleteHistory((int) $id);\n $this->configRepo->delete((int) $id);\n\n $_SESSION['success'] = 'Konfiguration gelöscht.';\n header('Location: \/config');\n exit;\n }\n}\n"
}
}