fix flag internet mode

This commit is contained in:
test
2026-09-04 13:59:59 +02:00
parent 15713e70a4
commit 2fcaa1e2ff
4 changed files with 44 additions and 0 deletions
+6
View File
@@ -2,6 +2,12 @@
## Ultima modifica: 02/09/2026 ## Ultima modifica: 02/09/2026
## 02/09/2026 — Fix: Internet mode switch mostra sempre disabilitato dopo il toggle (cache 30s non invalidata)
- **Sintomo**: nel tab Computer → Azioni, togliendo/attivando "Internet mode" il form fa POST, la pagina ricarica tornando su "Stato client", e riaprendo "Azioni" lo switch risulta ancora nello stato precedente.
- **Analisi (causa radice)**: la chiamata API `saveInternetMode()` funziona correttamente (verificato empiricamente su localhost:55414: `clientsettings_save` con `t_clientid`+`overwrite=true`+`internet_mode_enabled` toggla e rilegge bene `internet_mode_enabled=true/false`). Anche il parsing PHP del campo duplicato `internet_mode` è corretto (hidden 0 + checkbox 1 → PHP tiene l'ULTIMO valore = 1 in enable). **Il vero bug** è la **session cache 30s** `urbackup_data_{serverid}_{itemtype}_{itemsid}` in `AssetTab::loadApiData()` (AssetTab.php:374-377) che NON veniva invalidata dopo alcuna azione mutante: dopo il redirect il tab mostrava i dati cached (stato vecchio) per max 30s.
- **Fix**: nuovo `AssetTab::clearApiCache(CommonDBTM $item)` (AssetTab.php, ricalcola la stessa cache_key e fa `unset($_SESSION[$cache_key])`); chiamato da `front/asset.form.php` prima di ogni azione mutante (backup incr/full file/image, create/delete client, set_internet_mode, set_default_dirs). Così dopo il redirect `loadApiData()` ri-fetches dati freschi e lo switch riflette lo stato reale del server.
- Nessun bump versione (solo fix UI/comportamento, nessuna modifica DB, regola 6). Lint `php -l` OK. **Verifica UI utente OBBLIGATORIA**: attivare/disattivare Internet mode e confermare che lo switch resti nello stato scelto dopo il ricaricamento (anche subito, senza attendere).
## 02/09/2026 — Pulizia capacity all'uninstall (nessun bump versione) ## 02/09/2026 — Pulizia capacity all'uninstall (nessun bump versione)
- **`install/uninstall.php`**: nuova `plugin_urbackup_uninstall_cleanup_capacities(Migration, DBmysql)` — rimuove il riferimento `GlpiPlugin\Urbackup\Capacity\UrBackupCapacity` dalla colonna JSON `capacities` di `glpi_assetdefinitions` (query builder `$DB->request()/update()`, idempotente, filtrata sulle righe con `capacities <> '[]'`). Invocata in `plugin_urbackup_uninstall_process()` con `global $DB`. - **`install/uninstall.php`**: nuova `plugin_urbackup_uninstall_cleanup_capacities(Migration, DBmysql)` — rimuove il riferimento `GlpiPlugin\Urbackup\Capacity\UrBackupCapacity` dalla colonna JSON `capacities` di `glpi_assetdefinitions` (query builder `$DB->request()/update()`, idempotente, filtrata sulle righe con `capacities <> '[]'`). Invocata in `plugin_urbackup_uninstall_process()` con `global $DB`.
- Motivo: altrimenti resta una reference orfana dopo la disinstallazione. Il core GLPI la ignora in sicurezza (`AssetDefinition::decodeCapacities()`/`AssetDefinition.php:698-701`, "May be a previously enabled capacity from a disabled plugin"), ma ora il DB resta pulito. - Motivo: altrimenti resta una reference orfana dopo la disinstallazione. Il core GLPI la ignora in sicurezza (`AssetDefinition::decodeCapacities()`/`AssetDefinition.php:698-701`, "May be a previously enabled capacity from a disabled plugin"), ma ora il DB resta pulito.
+1
View File
@@ -120,6 +120,7 @@ plugin_urbackup/
- `server_test.ajax.php`: entity-aware `check()` authorization; added `public/js/urbackup.js` (registered via `ADD_JAVASCRIPT`) that sends the `X-Glpi-Csrf-Token` header on plugin AJAX POSTs; `dropdown_host.ajax.php` now requires READ right - `server_test.ajax.php`: entity-aware `check()` authorization; added `public/js/urbackup.js` (registered via `ADD_JAVASCRIPT`) that sends the `X-Glpi-Csrf-Token` header on plugin AJAX POSTs; `dropdown_host.ajax.php` now requires READ right
- Renamed the server form client tabs to be clearer: "Linked clients" → "Managed clients", "Unlinked clients" → "Linkable clients", "Missing clients" → "Clients to manage"; removed the sort/search on the missing clients table to match the other tab layouts; updated it_IT/de_DE/en_GB translations and recompiled locales - Renamed the server form client tabs to be clearer: "Linked clients" → "Managed clients", "Unlinked clients" → "Linkable clients", "Missing clients" → "Clients to manage"; removed the sort/search on the missing clients table to match the other tab layouts; updated it_IT/de_DE/en_GB translations and recompiled locales
- **Uninstall cleanup**: the UrBackup capacity reference (`GlpiPlugin\Urbackup\Capacity\UrBackupCapacity`) is now removed from the `capacities` JSON column of `glpi_assetdefinitions` so the database keeps no stale reference to the disinstalled plugin (GLPI core safely ignores such orphaned capacities, but they are now cleaned up) - **Uninstall cleanup**: the UrBackup capacity reference (`GlpiPlugin\Urbackup\Capacity\UrBackupCapacity`) is now removed from the `capacities` JSON column of `glpi_assetdefinitions` so the database keeps no stale reference to the disinstalled plugin (GLPI core safely ignores such orphaned capacities, but they are now cleaned up)
- **Internet mode fix**: the "Enable Internet mode" switch in the asset tab no longer appears stuck on its previous state after toggling. The 30 s API-data session cache was not invalidated after mutations, so the tab kept showing stale settings right after the redirect; a new `AssetTab::clearApiCache()` now clears it on every mutating action (backups, create/delete client, internet mode, default dirs)
### 0.7.2 ### 0.7.2
- UrBackup on Computer is now configurable: new `enable_computer` setting on the plugin configuration page (previously always enabled, hardcoded) - UrBackup on Computer is now configurable: new `enable_computer` setting on the plugin configuration page (previously always enabled, hardcoded)
+8
View File
@@ -109,11 +109,13 @@ if (isset($_POST['execute'])) {
switch ($action) { switch ($action) {
case 'incremental_file_backup': case 'incremental_file_backup':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
AssetTab::clearApiCache($item);
AssetTab::startBackup($item, 'file'); AssetTab::startBackup($item, 'file');
} }
break; break;
case 'full_file_backup': case 'full_file_backup':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
AssetTab::clearApiCache($item);
$link = ServerAsset::getLinkForAsset($itemtype, $items_id, false); $link = ServerAsset::getLinkForAsset($itemtype, $items_id, false);
if ($link !== null) { if ($link !== null) {
$server = new \GlpiPlugin\Urbackup\Server(); $server = new \GlpiPlugin\Urbackup\Server();
@@ -130,11 +132,13 @@ if (isset($_POST['execute'])) {
break; break;
case 'incremental_image_backup': case 'incremental_image_backup':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
AssetTab::clearApiCache($item);
AssetTab::startBackup($item, 'image'); AssetTab::startBackup($item, 'image');
} }
break; break;
case 'full_image_backup': case 'full_image_backup':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
AssetTab::clearApiCache($item);
$link = ServerAsset::getLinkForAsset($itemtype, $items_id, false); $link = ServerAsset::getLinkForAsset($itemtype, $items_id, false);
if ($link !== null) { if ($link !== null) {
$server = new \GlpiPlugin\Urbackup\Server(); $server = new \GlpiPlugin\Urbackup\Server();
@@ -151,6 +155,7 @@ if (isset($_POST['execute'])) {
break; break;
case 'create_client': case 'create_client':
if (Profile::canCurrentUser(CREATE)) { if (Profile::canCurrentUser(CREATE)) {
AssetTab::clearApiCache($item);
$link = ServerAsset::getLinkForAsset($itemtype, $items_id, false); $link = ServerAsset::getLinkForAsset($itemtype, $items_id, false);
if ($link !== null) { if ($link !== null) {
$server = new \GlpiPlugin\Urbackup\Server(); $server = new \GlpiPlugin\Urbackup\Server();
@@ -167,6 +172,7 @@ if (isset($_POST['execute'])) {
break; break;
case 'delete_client': case 'delete_client':
if (Profile::canCurrentUser(PURGE)) { if (Profile::canCurrentUser(PURGE)) {
AssetTab::clearApiCache($item);
$link = ServerAsset::getLinkForAsset($itemtype, $items_id, false); $link = ServerAsset::getLinkForAsset($itemtype, $items_id, false);
if ($link !== null) { if ($link !== null) {
$server = new \GlpiPlugin\Urbackup\Server(); $server = new \GlpiPlugin\Urbackup\Server();
@@ -184,6 +190,7 @@ if (isset($_POST['execute'])) {
case 'set_internet_mode': case 'set_internet_mode':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
$enabled = (int) ($_POST['internet_mode'] ?? 0) === 1; $enabled = (int) ($_POST['internet_mode'] ?? 0) === 1;
AssetTab::clearApiCache($item);
if (!AssetTab::saveInternetMode($item, $enabled)) { if (!AssetTab::saveInternetMode($item, $enabled)) {
Session::addMessageAfterRedirect( Session::addMessageAfterRedirect(
__('Failed to save internet mode', 'urbackup'), __('Failed to save internet mode', 'urbackup'),
@@ -196,6 +203,7 @@ if (isset($_POST['execute'])) {
case 'set_default_dirs': case 'set_default_dirs':
if (Profile::canCurrentUser(UPDATE)) { if (Profile::canCurrentUser(UPDATE)) {
$dirs = (string) ($_POST['default_dirs'] ?? ''); $dirs = (string) ($_POST['default_dirs'] ?? '');
AssetTab::clearApiCache($item);
if (!AssetTab::saveDefaultDirs($item, $dirs)) { if (!AssetTab::saveDefaultDirs($item, $dirs)) {
Session::addMessageAfterRedirect( Session::addMessageAfterRedirect(
__('Failed to save default directories', 'urbackup'), __('Failed to save default directories', 'urbackup'),
+29
View File
@@ -998,6 +998,35 @@ class AssetTab extends CommonDBTM
return false; return false;
} }
/**
* Clear the API data session cache for the given asset.
*
* `loadApiData()` caches the API results (client status, settings, logs)
* for 30 seconds under a per-asset session key. Any action that mutates
* the client on the UrBackup server must clear this cache, otherwise the
* tab keeps displaying stale data (e.g. the Internet mode switch still
* showing the previous state) right after the redirect.
*
* @param CommonDBTM $item Asset whose cached API data must be cleared
*
* @return void
*/
public static function clearApiCache(CommonDBTM $item): void
{
$link = ServerAsset::getLinkForAsset($item::class, (int) $item->fields['id'], false);
if ($link === null) {
return;
}
$server_id = (int) ($link['plugin_urbackup_servers_id'] ?? 0);
if ($server_id <= 0) {
return;
}
$cache_key = 'urbackup_data_' . $server_id . '_' . $item::class . '_' . $item->fields['id'];
unset($_SESSION[$cache_key]);
}
public static function saveInternetMode(CommonDBTM $item, bool $enabled): bool public static function saveInternetMode(CommonDBTM $item, bool $enabled): bool
{ {
$link = ServerAsset::getLinkForAsset($item::class, (int) $item->fields['id'], false); $link = ServerAsset::getLinkForAsset($item::class, (int) $item->fields['id'], false);