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

@@ -132,6 +132,7 @@ class LayoutHelper
'whois_failed' => 'exclamation-circle',
'system_welcome' => 'hand-sparkles',
'system_upgrade' => 'arrow-up',
'update_available' => 'cloud-download-alt',
default => 'bell'
};
}
@@ -154,6 +155,7 @@ class LayoutHelper
'whois_failed' => 'gray',
'system_welcome' => 'purple',
'system_upgrade' => 'indigo',
'update_available' => 'blue',
default => 'gray'
};
}
@@ -182,5 +184,47 @@ class LayoutHelper
];
}
}
/**
* Get update badge info for the top menu (admin only).
* Uses cached update check data; no GitHub API call.
* Returns ['show' => bool, 'available' => bool, 'label' => string].
*/
public static function getUpdateBadgeInfo(): array
{
try {
$settingModel = new Setting();
$updateSettings = $settingModel->getUpdateSettings();
$badgeEnabled = ($updateSettings['update_badge_enabled'] ?? '1') !== '0';
if (!$badgeEnabled) {
return ['show' => false, 'available' => false, 'label' => ''];
}
$current = $settingModel->getAppVersion();
$latestVersion = $updateSettings['latest_available_version'] ?? null;
$channel = $updateSettings['update_channel'] ?? 'stable';
$commitsBehind = (int) ($updateSettings['commits_behind_count'] ?? 0);
$available = false;
$label = '';
if ($latestVersion && version_compare($latestVersion, $current, '>')) {
$available = true;
$label = 'v' . $latestVersion;
}
if ($channel === 'latest' && $commitsBehind > 0 && !$available) {
$available = true;
$label = $commitsBehind . ' commit' . ($commitsBehind !== 1 ? 's' : '');
}
return [
'show' => $available,
'available' => $available,
'label' => $label,
];
} catch (\Exception $e) {
return ['show' => false, 'available' => false, 'label' => ''];
}
}
}