Add import/export and update system

Implement CSV/JSON import and export for domains, notification groups and tags (with masking for sensitive channel data), including size/format validation, in-memory CSV building, and logging. Add tag transfer and bulk transfer actions (admin-only). Introduce a new update system: Add UpdateController and UpdateService, migration 025_add_update_system_v1.1.3.sql, and installer changes to include the new migration and version handling; provide endpoints to check, apply, rollback and configure updates. Update helpers and UI bits: add getUpdateBadgeInfo in LayoutHelper, update notification icons/redirects, and add getMaxUploadSize in ViewHelper. Misc: add NotificationGroup::findByName, tweak .gitignore backups path, and update related views and routes.
This commit is contained in:
Hosteroid
2026-02-11 17:43:23 +02:00
parent 0c759cdd1d
commit 3688c8b71b
32 changed files with 4268 additions and 350 deletions

View File

@@ -98,5 +98,21 @@ class NotificationGroup extends Model
$stmt->execute([$userId]);
return $stmt->rowCount();
}
/**
* Find a notification group by name
*/
public function findByName(string $name, ?int $userId = null): ?array
{
if ($userId) {
$stmt = $this->db->prepare("SELECT * FROM notification_groups WHERE name = ? AND user_id = ? LIMIT 1");
$stmt->execute([$name, $userId]);
} else {
$stmt = $this->db->prepare("SELECT * FROM notification_groups WHERE name = ? LIMIT 1");
$stmt->execute([$name]);
}
$result = $stmt->fetch();
return $result ?: null;
}
}

View File

@@ -122,7 +122,7 @@ class Setting extends Model
*/
public function getAppVersion(): string
{
return $this->getValue('app_version', '1.1.2');
return $this->getValue('app_version', '1.1.3');
}
/**
@@ -322,6 +322,27 @@ class Setting extends Model
return $this->setValue('notification_status_triggers', $value);
}
/**
* Get update settings
*/
public function getUpdateSettings(): array
{
return [
'update_channel' => $this->getValue('update_channel', 'stable'),
'last_update_check' => $this->getValue('last_update_check', null),
'latest_available_version' => $this->getValue('latest_available_version', null),
'latest_release_notes' => $this->getValue('latest_release_notes', ''),
'latest_release_url' => $this->getValue('latest_release_url', ''),
'latest_release_published_at' => $this->getValue('latest_release_published_at', ''),
'installed_commit_sha' => $this->getValue('installed_commit_sha', null),
'update_backup_path' => $this->getValue('update_backup_path', null),
'update_db_backup_path' => $this->getValue('update_db_backup_path', null),
'commits_behind_count' => (int) $this->getValue('commits_behind_count', 0),
'latest_remote_sha' => $this->getValue('latest_remote_sha', ''),
'update_badge_enabled' => $this->getValue('update_badge_enabled', '1'),
];
}
/**
* Clear old notification logs
*/