diff --git a/public/assets/js/bridge/blocks-api.js b/public/assets/js/bridge/blocks-api.js index 1dd1afc..22337a0 100644 --- a/public/assets/js/bridge/blocks-api.js +++ b/public/assets/js/bridge/blocks-api.js @@ -508,6 +508,10 @@ // 🚨 KRITISCH: Server erwartet das Feld 'json' json: jsonProjectDataRaw, }; + const versionId = Number(B.CURRENT_VERSION_ID || window.CURRENT_VERSION_ID || 0); + if (versionId > 0) { + dataToSend.version_id = versionId; + } const activateNext = B.NEXT_ACTIVATE_VERSION || window.NEXT_ACTIVATE_VERSION; if (activateNext) { dataToSend.activate_version = 1; diff --git a/public/assets/js/bridge/rte-editor.js b/public/assets/js/bridge/rte-editor.js index c9f02c3..86f328b 100644 --- a/public/assets/js/bridge/rte-editor.js +++ b/public/assets/js/bridge/rte-editor.js @@ -33,6 +33,14 @@ } } catch {} } + if (!html) { + try { + const body = editor.Canvas && editor.Canvas.getBody ? editor.Canvas.getBody() : null; + if (body && body.innerHTML) { + html = String(body.innerHTML || ''); + } + } catch {} + } try { const wrapper = editor.getWrapper && editor.getWrapper(); if (wrapper && wrapper.find) { diff --git a/public/assets/js/ui-editor.js b/public/assets/js/ui-editor.js index df6b993..46eac94 100644 --- a/public/assets/js/ui-editor.js +++ b/public/assets/js/ui-editor.js @@ -327,6 +327,18 @@ export function initEditor() { const isActive = !!(currentVersionMeta && Number(currentVersionMeta.is_active) === 1); versionActiveBadge.classList.toggle('hidden', !isActive); } + const win = iframe?.contentWindow; + if (win && win.BridgeParts) { + const canOverwrite = !!(currentVersionMeta + && Number(currentVersionMeta.is_active) === 0 + && Number(currentVersionMeta.was_active) === 0); + win.BridgeParts.CURRENT_VERSION_ID = canOverwrite ? currentVersionId : 0; + } else if (win) { + const canOverwrite = !!(currentVersionMeta + && Number(currentVersionMeta.is_active) === 0 + && Number(currentVersionMeta.was_active) === 0); + win.CURRENT_VERSION_ID = canOverwrite ? currentVersionId : 0; + } } function renderVersionOptions(items, opts = {}) { @@ -856,6 +868,12 @@ export function initEditor() { activateNext = decision === 'yes'; } + const overwriteVersionId = (currentVersionMeta + && Number(currentVersionMeta.is_active) === 0 + && Number(currentVersionMeta.was_active) === 0) + ? Number(currentVersionId || 0) + : 0; + if (currentEditorType === 'craftjs') { const html = craftEditor ? craftEditor.getContent() : ''; const craftJson = craftEditor && craftEditor.getCraftJson @@ -863,6 +881,7 @@ export function initEditor() { : JSON.stringify({ html }); const payload = { html, craft_json: craftJson, editor_type: 'craftjs', section_id: current.section.id }; if (activateNext) payload.activate_version = 1; + if (overwriteVersionId) payload.version_id = overwriteVersionId; const res = await apiUpdate('content', current.id, payload); if (res?.ok) ok('Gespeichert'); else err(res?.error || 'Speichern fehlgeschlagen'); @@ -878,6 +897,14 @@ export function initEditor() { win.NEXT_ACTIVATE_VERSION = 1; } } + if (overwriteVersionId) { + const win = iframe?.contentWindow; + if (win && win.BridgeParts) { + win.BridgeParts.CURRENT_VERSION_ID = overwriteVersionId; + } else if (win) { + win.CURRENT_VERSION_ID = overwriteVersionId; + } + } const okSave = await delegateCommand('save-data'); if (okSave) { setTimeout(async () => { diff --git a/src/ApiKernel.php b/src/ApiKernel.php index 710c57a..71d0ad1 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -1066,6 +1066,8 @@ class ApiKernel break; } } + $requestedVersionId = (int)$this->val($this->in, ['version_id', 'versionId', 'version'], 0); + $updatedExistingVersion = false; $set = implode(',', array_map(static fn($c) => "`$c` = :$c", array_keys($data))); $data['id'] = $id; @@ -1074,7 +1076,45 @@ class ApiKernel $stmt = $this->pdo->prepare($sql); foreach ($data as $k => $v) $stmt->bindValue(":$k", $v); $stmt->execute(); - if ($shouldSnapshot) { + if ($shouldSnapshot && $requestedVersionId > 0) { + try { + $versionsTable = $this->contentVersionsTable(); + if ($this->tableExists($versionsTable)) { + $vCols = $this->resolveContentVersionColumns($versionsTable); + $stmt = $this->pdo->prepare( + "SELECT `id`,`content_id`,`customer_id`,`section_id`,`is_active`,`was_active` FROM `$versionsTable` + WHERE `id` = :id AND `customer_id` = :cid AND `content_id` = :content LIMIT 1" + ); + $stmt->execute([':id' => $requestedVersionId, ':cid' => $customerId, ':content' => $id]); + $versionRow = $stmt->fetch(); + if ($versionRow && (int)($versionRow['is_active'] ?? 0) === 0 && (int)($versionRow['was_active'] ?? 0) === 0) { + $vdata = []; + if ($htmlCol && isset($data[$htmlCol]) && !empty($vCols['html'])) $vdata[$vCols['html']] = $data[$htmlCol]; + if ($jsonCol && isset($data[$jsonCol]) && !empty($vCols['json'])) $vdata[$vCols['json']] = $data[$jsonCol]; + if ($craftCol && isset($data[$craftCol]) && !empty($vCols['craft'])) $vdata[$vCols['craft']] = $data[$craftCol]; + if ($settingsCol && isset($data[$settingsCol]) && !empty($vCols['settings'])) $vdata[$vCols['settings']] = $data[$settingsCol]; + if ($editorCol && isset($data[$editorCol]) && !empty($vCols['editor'])) $vdata[$vCols['editor']] = $data[$editorCol]; + if ($vdata) { + $setVersion = implode(',', array_map(static fn($c) => "`$c` = :$c", array_keys($vdata))); + $vdata['id'] = $requestedVersionId; + $vdata['customer_id'] = $customerId; + $vdata['content_id'] = $id; + $sql = "UPDATE `$versionsTable` SET $setVersion WHERE `id` = :id AND `customer_id` = :customer_id AND `content_id` = :content_id LIMIT 1"; + $stmt = $this->pdo->prepare($sql); + foreach ($vdata as $k => $v) $stmt->bindValue(":$k", $v); + $stmt->execute(); + $updatedExistingVersion = $stmt->rowCount() > 0; + if ($updatedExistingVersion && $activateVersion) { + $this->activateContentVersion($customerId, (int)$id, (int)$requestedVersionId); + } + } + } + } + } catch (Throwable $e) { + $updatedExistingVersion = false; + } + } + if ($shouldSnapshot && !$updatedExistingVersion) { try { $stmt = $this->pdo->prepare("SELECT * FROM `$itemsTable` WHERE `customer_id` = :cid AND `id` = :id LIMIT 1"); $stmt->execute([':cid' => $customerId, ':id' => $id]);