This commit is contained in:
2026-01-19 01:12:44 +01:00
parent e761b62ac2
commit 0a65701e0e
4 changed files with 230 additions and 16 deletions

View File

@@ -415,6 +415,8 @@ class ApiKernel
if ($descCol && isset($r[$descCol])) $item['desc'] = $r[$descCol];
if ($catCol && isset($r[$catCol])) $item['category'] = $r[$catCol];
if ($updCol && isset($r[$updCol])) $item['updated_at'] = $r[$updCol];
$createdCol = $this->firstExisting($allCols, ['created_at', 'created', 'createdAt']);
if ($createdCol && isset($r[$createdCol])) $item['created_at'] = $r[$createdCol];
// Lade HTML und JSON aus den korrekten Spalten
$htmlCol = $this->firstExisting($allCols, ['html', 'body', 'markup', 'content']);
@@ -1749,6 +1751,8 @@ class ApiKernel
$this->ensureRole($user, ['owner', 'admin']);
$customerId = (int)($user['customer_id'] ?? 0);
$settings = $this->ensureSettingsTokens($customerId, $this->getCustomerSettings($customerId));
$this->ensureAuthUserListSortColumn();
$settings['list_sort'] = $this->resolveUserListSort($user, $customerId);
$this->respond(['ok' => true, 'settings' => $settings]);
}
@@ -1759,21 +1763,30 @@ class ApiKernel
$customerId = (int)($user['customer_id'] ?? 0);
if ($customerId <= 0) $this->fail('Customer context missing', null, 500);
$bridgeUrl = trim((string)($this->in['bridge_url'] ?? ''));
$bridgeToken = trim((string)($this->in['bridge_token'] ?? ''));
$senderToken = trim((string)($this->in['sender_token'] ?? ''));
$externalToken = trim((string)($this->in['external_api_token'] ?? ''));
$editorDefault = strtolower(trim((string)($this->in['editor_default'] ?? '')));
$settings = $this->getCustomerSettings($customerId);
$hasBridgeUrl = array_key_exists('bridge_url', $this->in);
$hasBridgeToken = array_key_exists('bridge_token', $this->in);
$hasSenderToken = array_key_exists('sender_token', $this->in);
$hasExternalToken = array_key_exists('external_api_token', $this->in);
$hasEditorDefault = array_key_exists('editor_default', $this->in);
$hasListSort = array_key_exists('list_sort', $this->in);
$hasBridgeTables = array_key_exists('bridge_tables', $this->in);
$bridgeUrl = $hasBridgeUrl ? trim((string)($this->in['bridge_url'] ?? '')) : (string)($settings['bridge_url'] ?? '');
$bridgeToken = $hasBridgeToken ? trim((string)($this->in['bridge_token'] ?? '')) : (string)($settings['bridge_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'] ?? '');
$editorDefault = $hasEditorDefault ? strtolower(trim((string)($this->in['editor_default'] ?? ''))) : strtolower((string)($settings['editor_default'] ?? ''));
$listSort = $hasListSort ? strtolower(trim((string)($this->in['list_sort'] ?? ''))) : '';
$rotateBridge = !empty($this->in['rotate_bridge_token']);
$rotateSender = !empty($this->in['rotate_sender_token']);
$rotateExternal = !empty($this->in['rotate_external_token']);
$bridgeTables = $this->normalizeBridgeTables($this->in['bridge_tables'] ?? []);
$bridgeTables = $hasBridgeTables ? $this->normalizeBridgeTables($this->in['bridge_tables'] ?? []) : ($settings['bridge_tables'] ?? []);
if ($bridgeUrl && !filter_var($bridgeUrl, FILTER_VALIDATE_URL)) {
$this->fail('Ungültige Bridge-URL', null, 422);
}
$settings = $this->getCustomerSettings($customerId);
if ($rotateBridge || $bridgeToken === '') $bridgeToken = $this->generateToken();
if ($rotateSender || $senderToken === '') $senderToken = $this->generateToken();
if ($rotateExternal || $externalToken === '') $externalToken = $this->generateToken();
@@ -1781,6 +1794,9 @@ class ApiKernel
if ($editorDefault !== '' && !in_array($editorDefault, ['grapesjs', 'craftjs'], true)) {
$this->fail('Ungültiger Editor-Typ', null, 422);
}
if ($listSort !== '' && !in_array($listSort, ['created_asc', 'name_asc', 'name_desc', 'updated_desc'], true)) {
$this->fail('Ungültige Sortierung', null, 422);
}
$settings = $this->saveCustomerSettings($customerId, [
'bridge_url' => $bridgeUrl,
@@ -1790,6 +1806,11 @@ class ApiKernel
'editor_default' => $editorDefault ?: null,
'bridge_tables' => $bridgeTables,
]);
if ($hasListSort) {
$this->ensureAuthUserListSortColumn();
$this->updateUserListSort($user, $customerId, $listSort ?: null);
}
$settings['list_sort'] = $this->resolveUserListSort($user, $customerId, $listSort);
$this->respond(['ok' => true, 'settings' => $settings]);
}
@@ -2734,6 +2755,100 @@ SQL;
];
}
private function ensureAuthUserListSortColumn(): void
{
if (!$this->pdo) {
return;
}
$cols = $this->authUserColumns();
$table = $cols['table'];
try {
$columns = $this->tableColumns($table);
} catch (Throwable $e) {
$this->fail('User-Tabelle konnte nicht gelesen werden', $e->getMessage(), 500);
return;
}
if (in_array('list_sort', $columns, true)) {
return;
}
try {
$sql = 'ALTER TABLE `' . $table . '` ADD COLUMN `list_sort` varchar(32) DEFAULT NULL';
$this->pdo->exec($sql);
} catch (Throwable $e) {
$this->fail('User-Tabelle konnte nicht aktualisiert werden', $e->getMessage(), 500);
}
}
private function getUserListSort(array $user, int $customerId): ?string
{
if (!$this->pdo) {
return null;
}
$userId = (int)($user['id'] ?? 0);
if ($userId <= 0) {
return null;
}
$cols = $this->authUserColumns();
$table = $cols['table'];
$dbCols = $this->tableColumns($table);
if (!$this->columnExists($dbCols, 'list_sort')) {
return null;
}
$where = sprintf('`%s` = :id', $cols['col_id']);
$params = [':id' => $userId];
if ($customerId > 0 && $this->columnExists($dbCols, $cols['col_customer'])) {
$where .= sprintf(' AND `%s` = :cid', $cols['col_customer']);
$params[':cid'] = $customerId;
}
$sql = sprintf('SELECT `list_sort` FROM `%s` WHERE %s LIMIT 1', $table, $where);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch();
if (!$row) {
return null;
}
return $row['list_sort'] !== null ? (string)$row['list_sort'] : null;
}
private function updateUserListSort(array $user, int $customerId, ?string $value): void
{
if (!$this->pdo) {
return;
}
$userId = (int)($user['id'] ?? 0);
if ($userId <= 0) {
return;
}
$cols = $this->authUserColumns();
$table = $cols['table'];
$dbCols = $this->tableColumns($table);
if (!$this->columnExists($dbCols, 'list_sort')) {
return;
}
$where = sprintf('`%s` = :id', $cols['col_id']);
$params = [
':id' => $userId,
':value' => $value,
];
if ($customerId > 0 && $this->columnExists($dbCols, $cols['col_customer'])) {
$where .= sprintf(' AND `%s` = :cid', $cols['col_customer']);
$params[':cid'] = $customerId;
}
$sql = sprintf('UPDATE `%s` SET `list_sort` = :value WHERE %s LIMIT 1', $table, $where);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
}
private function resolveUserListSort(array $user, int $customerId, string $fallback = ''): string
{
$value = $fallback !== '' ? $fallback : (string)($this->getUserListSort($user, $customerId) ?? '');
$allowed = ['created_asc', 'name_asc', 'name_desc', 'updated_desc'];
if ($value === '' || !in_array($value, $allowed, true)) {
return 'created_asc';
}
return $value;
}
private function ensureAuthUserHydrated(array $user): array
{
$role = (string)($user['role'] ?? '');