asd
This commit is contained in:
@@ -1 +1 @@
|
|||||||
1.2.39
|
1.2.40
|
||||||
@@ -15,6 +15,9 @@ require dirname(__DIR__) . '/../structure/layout_start.php';
|
|||||||
<option value="grapesjs">GrapesJS</option>
|
<option value="grapesjs">GrapesJS</option>
|
||||||
<option value="craftjs">Craft.js</option>
|
<option value="craftjs">Craft.js</option>
|
||||||
</select>
|
</select>
|
||||||
|
<label class="block text-sm text-slate-600">Versionen aufbewahren (0 = unbegrenzt)
|
||||||
|
<input type="number" name="versions_retention" class="input mt-1" min="0" step="1" placeholder="0">
|
||||||
|
</label>
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<button type="submit" class="btn">Einstellungen speichern</button>
|
<button type="submit" class="btn">Einstellungen speichern</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -442,6 +442,12 @@ function fillSettingsForm(settings) {
|
|||||||
if (settingsForm.sender_token) settingsForm.sender_token.value = settings.sender_token || '';
|
if (settingsForm.sender_token) settingsForm.sender_token.value = settings.sender_token || '';
|
||||||
if (settingsForm.external_api_token) settingsForm.external_api_token.value = settings.external_api_token || '';
|
if (settingsForm.external_api_token) settingsForm.external_api_token.value = settings.external_api_token || '';
|
||||||
if (settingsForm.editor_default) settingsForm.editor_default.value = settings.editor_default || 'grapesjs';
|
if (settingsForm.editor_default) settingsForm.editor_default.value = settings.editor_default || 'grapesjs';
|
||||||
|
if (settingsForm.versions_retention) {
|
||||||
|
const retention = Number.isFinite(Number(settings.versions_retention))
|
||||||
|
? Number(settings.versions_retention)
|
||||||
|
: 0;
|
||||||
|
settingsForm.versions_retention.value = String(Math.max(0, retention));
|
||||||
|
}
|
||||||
refreshAdminTables(settings.bridge_setup?.tables || [], settings.bridge_tables || []);
|
refreshAdminTables(settings.bridge_setup?.tables || [], settings.bridge_tables || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,6 +496,11 @@ async function submitSettingsForm(ev) {
|
|||||||
if (settingsForm.sender_token) data.sender_token = settingsForm.sender_token.value.trim();
|
if (settingsForm.sender_token) data.sender_token = settingsForm.sender_token.value.trim();
|
||||||
if (settingsForm.external_api_token) data.external_api_token = settingsForm.external_api_token.value.trim();
|
if (settingsForm.external_api_token) data.external_api_token = settingsForm.external_api_token.value.trim();
|
||||||
if (settingsForm.editor_default) data.editor_default = settingsForm.editor_default.value;
|
if (settingsForm.editor_default) data.editor_default = settingsForm.editor_default.value;
|
||||||
|
if (settingsForm.versions_retention) {
|
||||||
|
const raw = settingsForm.versions_retention.value.trim();
|
||||||
|
const parsed = raw === '' ? 0 : Number(raw);
|
||||||
|
data.versions_retention = Number.isFinite(parsed) ? Math.max(0, Math.floor(parsed)) : 0;
|
||||||
|
}
|
||||||
if (adminTablesAllSelect && adminTablesSelectedSelect) {
|
if (adminTablesAllSelect && adminTablesSelectedSelect) {
|
||||||
const bridgeTables = normalizeTableList(state.settings.bridge_tables || []);
|
const bridgeTables = normalizeTableList(state.settings.bridge_tables || []);
|
||||||
data.bridge_tables = bridgeTables;
|
data.bridge_tables = bridgeTables;
|
||||||
|
|||||||
@@ -431,14 +431,7 @@ class ApiKernel
|
|||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$newId = (int)$this->pdo->lastInsertId();
|
$newId = (int)$this->pdo->lastInsertId();
|
||||||
|
|
||||||
$cleanup = $this->pdo->prepare(
|
$this->applyContentVersionRetention($customerId, $contentId);
|
||||||
"DELETE FROM `$table` WHERE `id` IN (
|
|
||||||
SELECT `id` FROM (
|
|
||||||
SELECT `id` FROM `$table` WHERE `content_id` = :cid ORDER BY `id` DESC LIMIT 10, 1000000
|
|
||||||
) t
|
|
||||||
)"
|
|
||||||
);
|
|
||||||
$cleanup->execute([':cid' => $contentId]);
|
|
||||||
return $newId;
|
return $newId;
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
// Versioning darf nicht das Speichern blockieren.
|
// Versioning darf nicht das Speichern blockieren.
|
||||||
@@ -446,6 +439,35 @@ class ApiKernel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function applyContentVersionRetention(int $customerId, int $contentId): void
|
||||||
|
{
|
||||||
|
$limit = $this->getContentVersionRetentionLimit($customerId);
|
||||||
|
if ($limit <= 0) return;
|
||||||
|
$table = $this->contentVersionsTable();
|
||||||
|
if (!$this->tableExists($table)) return;
|
||||||
|
try {
|
||||||
|
$versionCols = $this->resolveContentVersionColumns($table);
|
||||||
|
$isActiveCol = $versionCols['is_active'];
|
||||||
|
$activeFilter = $isActiveCol ? " AND (`$isActiveCol` IS NULL OR `$isActiveCol` = 0)" : '';
|
||||||
|
$keepSql = "SELECT `id` FROM `$table` WHERE `content_id` = :cid ORDER BY `version_no` DESC, `id` DESC LIMIT :lim";
|
||||||
|
$deleteSql = "DELETE FROM `$table` WHERE `content_id` = :cid$activeFilter AND `id` NOT IN (SELECT `id` FROM ($keepSql) AS keep_ids)";
|
||||||
|
$stmt = $this->pdo->prepare($deleteSql);
|
||||||
|
$stmt->bindValue(':cid', $contentId, PDO::PARAM_INT);
|
||||||
|
$stmt->bindValue(':lim', $limit, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
// Retention darf nicht das Speichern blockieren.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContentVersionRetentionLimit(int $customerId): int
|
||||||
|
{
|
||||||
|
if ($customerId <= 0) return 0;
|
||||||
|
$settings = $this->getCustomerSettings($customerId);
|
||||||
|
$limit = (int)($settings['versions_retention'] ?? 0);
|
||||||
|
return max(0, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
private function activateContentVersion(int $customerId, int $contentId, int $versionId): bool
|
private function activateContentVersion(int $customerId, int $contentId, int $versionId): bool
|
||||||
{
|
{
|
||||||
$table = $this->contentVersionsTable();
|
$table = $this->contentVersionsTable();
|
||||||
@@ -3711,13 +3733,14 @@ class ApiKernel
|
|||||||
$hasSenderToken = array_key_exists('sender_token', $this->in);
|
$hasSenderToken = array_key_exists('sender_token', $this->in);
|
||||||
$hasExternalToken = array_key_exists('external_api_token', $this->in);
|
$hasExternalToken = array_key_exists('external_api_token', $this->in);
|
||||||
$hasEditorDefault = array_key_exists('editor_default', $this->in);
|
$hasEditorDefault = array_key_exists('editor_default', $this->in);
|
||||||
|
$hasVersionsRetention = array_key_exists('versions_retention', $this->in);
|
||||||
$hasListSort = array_key_exists('list_sort', $this->in);
|
$hasListSort = array_key_exists('list_sort', $this->in);
|
||||||
$hasBridgeTables = array_key_exists('bridge_tables', $this->in);
|
$hasBridgeTables = array_key_exists('bridge_tables', $this->in);
|
||||||
$rotateBridge = !empty($this->in['rotate_bridge_token']);
|
$rotateBridge = !empty($this->in['rotate_bridge_token']);
|
||||||
$rotateSender = !empty($this->in['rotate_sender_token']);
|
$rotateSender = !empty($this->in['rotate_sender_token']);
|
||||||
$rotateExternal = !empty($this->in['rotate_external_token']);
|
$rotateExternal = !empty($this->in['rotate_external_token']);
|
||||||
$onlyListSort = $hasListSort && !$hasBridgeUrl && !$hasBridgeToken && !$hasSenderToken && !$hasExternalToken
|
$onlyListSort = $hasListSort && !$hasBridgeUrl && !$hasBridgeToken && !$hasSenderToken && !$hasExternalToken
|
||||||
&& !$hasEditorDefault && !$hasBridgeTables && !$rotateBridge && !$rotateSender && !$rotateExternal;
|
&& !$hasEditorDefault && !$hasBridgeTables && !$hasVersionsRetention && !$rotateBridge && !$rotateSender && !$rotateExternal;
|
||||||
|
|
||||||
if (!$onlyListSort) {
|
if (!$onlyListSort) {
|
||||||
$this->ensureRole($user, ['owner', 'admin']);
|
$this->ensureRole($user, ['owner', 'admin']);
|
||||||
@@ -3730,6 +3753,7 @@ class ApiKernel
|
|||||||
$senderToken = $hasSenderToken ? trim((string)($this->in['sender_token'] ?? '')) : (string)($settings['sender_token'] ?? '');
|
$senderToken = $hasSenderToken ? trim((string)($this->in['sender_token'] ?? '')) : (string)($settings['sender_token'] ?? '');
|
||||||
$externalToken = $hasExternalToken ? trim((string)($this->in['external_api_token'] ?? '')) : (string)($settings['external_api_token'] ?? '');
|
$externalToken = $hasExternalToken ? trim((string)($this->in['external_api_token'] ?? '')) : (string)($settings['external_api_token'] ?? '');
|
||||||
$editorDefault = $hasEditorDefault ? strtolower(trim((string)($this->in['editor_default'] ?? ''))) : strtolower((string)($settings['editor_default'] ?? ''));
|
$editorDefault = $hasEditorDefault ? strtolower(trim((string)($this->in['editor_default'] ?? ''))) : strtolower((string)($settings['editor_default'] ?? ''));
|
||||||
|
$versionsRetention = $hasVersionsRetention ? (int)($this->in['versions_retention'] ?? 0) : (int)($settings['versions_retention'] ?? 0);
|
||||||
$listSort = $hasListSort ? strtolower(trim((string)($this->in['list_sort'] ?? ''))) : '';
|
$listSort = $hasListSort ? strtolower(trim((string)($this->in['list_sort'] ?? ''))) : '';
|
||||||
$bridgeTables = $hasBridgeTables ? $this->normalizeBridgeTables($this->in['bridge_tables'] ?? []) : ($settings['bridge_tables'] ?? []);
|
$bridgeTables = $hasBridgeTables ? $this->normalizeBridgeTables($this->in['bridge_tables'] ?? []) : ($settings['bridge_tables'] ?? []);
|
||||||
|
|
||||||
@@ -3749,6 +3773,9 @@ class ApiKernel
|
|||||||
if ($editorDefault !== '' && !in_array($editorDefault, ['grapesjs', 'craftjs'], true)) {
|
if ($editorDefault !== '' && !in_array($editorDefault, ['grapesjs', 'craftjs'], true)) {
|
||||||
$this->fail('Ungültiger Editor-Typ', null, 422);
|
$this->fail('Ungültiger Editor-Typ', null, 422);
|
||||||
}
|
}
|
||||||
|
if ($versionsRetention < 0) {
|
||||||
|
$this->fail('Ungültiger Aufbewahrungswert', null, 422);
|
||||||
|
}
|
||||||
|
|
||||||
$settings = $this->saveCustomerSettings($customerId, [
|
$settings = $this->saveCustomerSettings($customerId, [
|
||||||
'bridge_url' => $bridgeUrl,
|
'bridge_url' => $bridgeUrl,
|
||||||
@@ -3757,6 +3784,7 @@ class ApiKernel
|
|||||||
'external_api_token' => $externalToken,
|
'external_api_token' => $externalToken,
|
||||||
'editor_default' => $editorDefault ?: null,
|
'editor_default' => $editorDefault ?: null,
|
||||||
'bridge_tables' => $bridgeTables,
|
'bridge_tables' => $bridgeTables,
|
||||||
|
'versions_retention' => $versionsRetention,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$settings = $customerId ? $this->ensureSettingsTokens($customerId, $settings) : $settings;
|
$settings = $customerId ? $this->ensureSettingsTokens($customerId, $settings) : $settings;
|
||||||
@@ -4318,7 +4346,7 @@ class ApiKernel
|
|||||||
{
|
{
|
||||||
if ($customerId <= 0) return [];
|
if ($customerId <= 0) return [];
|
||||||
$this->ensureCustomerSettingsTableExists();
|
$this->ensureCustomerSettingsTableExists();
|
||||||
$allowed = ['bridge_url', 'bridge_token', 'sender_token', 'external_api_token', 'editor_default', 'bridge_tables', 'bridge_setup'];
|
$allowed = ['bridge_url', 'bridge_token', 'sender_token', 'external_api_token', 'editor_default', 'bridge_tables', 'bridge_setup', 'versions_retention'];
|
||||||
$fields = array_intersect_key($data, array_flip($allowed));
|
$fields = array_intersect_key($data, array_flip($allowed));
|
||||||
if (!$fields) return $this->getCustomerSettings($customerId);
|
if (!$fields) return $this->getCustomerSettings($customerId);
|
||||||
if (array_key_exists('bridge_tables', $fields)) {
|
if (array_key_exists('bridge_tables', $fields)) {
|
||||||
@@ -4384,6 +4412,11 @@ class ApiKernel
|
|||||||
if (empty($row['editor_default'])) {
|
if (empty($row['editor_default'])) {
|
||||||
$row['editor_default'] = 'grapesjs';
|
$row['editor_default'] = 'grapesjs';
|
||||||
}
|
}
|
||||||
|
if (!isset($row['versions_retention']) || $row['versions_retention'] === '') {
|
||||||
|
$row['versions_retention'] = 0;
|
||||||
|
} else {
|
||||||
|
$row['versions_retention'] = max(0, (int)$row['versions_retention']);
|
||||||
|
}
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user