diff --git a/config/current.ver b/config/current.ver index 930a24b..725ffd4 100644 --- a/config/current.ver +++ b/config/current.ver @@ -1 +1 @@ -1.2.26 \ No newline at end of file +1.2.27 \ No newline at end of file diff --git a/public/assets/js/ui-editor.js b/public/assets/js/ui-editor.js index fed0827..219d055 100644 --- a/public/assets/js/ui-editor.js +++ b/public/assets/js/ui-editor.js @@ -1144,7 +1144,12 @@ export function initEditor() { try { const okRefs = await confirmTemplateReferences('Deaktivieren'); if (!okRefs) return; - const res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: current.id } }); + let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: current.id } }); + if (res && res.ok === false && Array.isArray(res.references) && res.references.length) { + const ok = confirm('Dieses Template wird in anderen Templates verwendet. Trotzdem deaktivieren?'); + if (!ok) return; + res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: current.id, force: 1 } }); + } if (!res?.ok) throw new Error(res?.error || 'Deaktivieren fehlgeschlagen'); await loadVersionsForCurrent({ keepSelection: true, preferredId: currentVersionId }); toast('Aktive Version deaktiviert', true); diff --git a/public/assets/js/ui-list.js b/public/assets/js/ui-list.js index 38ccd56..35a1dc7 100644 --- a/public/assets/js/ui-list.js +++ b/public/assets/js/ui-list.js @@ -260,7 +260,12 @@ async function openTemplateManager(item, section) { const ok = await confirmTemplateReferences('Deaktivieren'); if (!ok) return; } - const res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: item.id } }); + let res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: item.id } }); + if (res && res.ok === false && Array.isArray(res.references) && res.references.length) { + const ok = confirm('Dieses Template wird in anderen Templates verwendet. Trotzdem deaktivieren?'); + if (!ok) return; + res = await apiAction('content_versions.deactivate', { method: 'POST', data: { content_id: item.id, force: 1 } }); + } toast(res && res.ok ? 'Aktive Version deaktiviert' : 'Deaktivieren fehlgeschlagen', !!(res && res.ok)); await loadVersions(); if (typeof window.loadList === 'function') window.loadList(section); @@ -270,7 +275,12 @@ async function openTemplateManager(item, section) { const versionRow = versions.find(v => Number(v.id) === vid); if (versionRow && Number(versionRow.is_active) === 1) return; if (!confirm('Version wirklich löschen?')) return; - const res = await apiAction('content_versions.delete', { method: 'POST', data: { id: vid, content_id: item.id } }); + let res = await apiAction('content_versions.delete', { method: 'POST', data: { id: vid, content_id: item.id } }); + if (res && res.ok === false && Array.isArray(res.references) && res.references.length) { + const ok = confirm('Dieses Template wird in anderen Templates verwendet. Trotzdem löschen?'); + if (!ok) return; + res = await apiAction('content_versions.delete', { method: 'POST', data: { id: vid, content_id: item.id, force: 1 } }); + } toast(res && res.ok ? 'Version gelöscht' : 'Löschen fehlgeschlagen', !!(res && res.ok)); await loadVersions(); if (typeof window.loadList === 'function') window.loadList(section); diff --git a/src/ApiKernel.php b/src/ApiKernel.php index a46a8b7..c594077 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -1240,6 +1240,7 @@ class ApiKernel $versionId = (int)$this->val($this->in, ['id', 'version_id', 'version'], 0); if ($versionId <= 0) $this->fail('version id required', null, 422); $contentId = (int)$this->val($this->in, ['content_id', 'content'], 0); + $force = (int)$this->val($this->in, ['force', 'override'], 0) === 1; $versionsTable = $this->contentVersionsTable(); $itemsTable = $this->contentItemsTable(); @@ -1323,32 +1324,35 @@ class ApiKernel if ($customerId <= 0) $this->fail('Customer context missing', null, 500); $contentId = (int)$this->val($this->in, ['content_id', 'content'], 0); if ($contentId <= 0) $this->fail('content_id required', null, 422); + $force = (int)$this->val($this->in, ['force', 'override'], 0) === 1; - $refsDebug = []; - $refs = $this->findTemplateReferences($customerId, $contentId, $refsDebug); - if (!empty($refsDebug)) { - $this->writeDebugLog('templates_references_debug', $refsDebug); - } - if (!empty($refs)) { - debug_log_write('templates_toggle', [ - 'time' => date(DATE_ATOM), - 'action' => 'content_versions.deactivate.blocked', - 'customer_id' => $customerId, - 'content_id' => $contentId, - 'references' => $refs, - 'input' => $this->in, - ], [ - 'append' => true, - 'json' => true, - 'newline' => true, - ]); - $this->respond([ - 'ok' => false, - 'error' => 'Template wird in anderen Templates verwendet', - 'content_id' => $contentId, - 'count' => count($refs), - 'references' => $refs, - ], 409); + if (!$force) { + $refsDebug = []; + $refs = $this->findTemplateReferences($customerId, $contentId, $refsDebug); + if (!empty($refsDebug)) { + $this->writeDebugLog('templates_references_debug', $refsDebug); + } + if (!empty($refs)) { + debug_log_write('templates_toggle', [ + 'time' => date(DATE_ATOM), + 'action' => 'content_versions.deactivate.blocked', + 'customer_id' => $customerId, + 'content_id' => $contentId, + 'references' => $refs, + 'input' => $this->in, + ], [ + 'append' => true, + 'json' => true, + 'newline' => true, + ]); + $this->respond([ + 'ok' => false, + 'error' => 'Template wird in anderen Templates verwendet', + 'content_id' => $contentId, + 'count' => count($refs), + 'references' => $refs, + ], 409); + } } $ok = $this->deactivateContentVersion($customerId, $contentId); @@ -1395,6 +1399,37 @@ class ApiKernel $this->fail('Active versions cannot be deleted', ['id' => $versionId], 422); } + if (!$force && $contentId > 0) { + $refsDebug = []; + $refs = $this->findTemplateReferences($customerId, $contentId, $refsDebug); + if (!empty($refsDebug)) { + $this->writeDebugLog('templates_references_debug', $refsDebug); + } + if (!empty($refs)) { + debug_log_write('templates_toggle', [ + 'time' => date(DATE_ATOM), + 'action' => 'content_versions.delete.blocked', + 'customer_id' => $customerId, + 'content_id' => $contentId, + 'version_id' => $versionId, + 'references' => $refs, + 'input' => $this->in, + ], [ + 'append' => true, + 'json' => true, + 'newline' => true, + ]); + $this->respond([ + 'ok' => false, + 'error' => 'Template wird in anderen Templates verwendet', + 'content_id' => $contentId, + 'version_id' => $versionId, + 'count' => count($refs), + 'references' => $refs, + ], 409); + } + } + $stmt = $this->pdo->prepare("DELETE FROM `$table` WHERE `id` = :id AND `customer_id` = :cid LIMIT 1"); $stmt->execute([':id' => $versionId, ':cid' => $customerId]); $this->respond(['ok' => true, 'deleted' => true, 'id' => $versionId]);