diff --git a/MEMORY.md b/MEMORY.md index 37bea8f..fc9478d 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -1,9 +1,21 @@ # MEMORY.md - Stato del Plugin UrBackup -## Ultima modifica: 31/08/2026 +## Ultima modifica: 02/09/2026 + +## 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`. +- 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. +- i18n: nuova stringa "UrBackup capacity removed from asset definitions" (it "Capacità UrBackup rimossa dalle definizioni di asset", de "UrBackup-Kapazität aus Asset-Definitionen entfernt", en identica), `.po`+`.mo` ricompilati (msgfmt OK 3/3). +- Doc aggiornate: README Changelog 0.7.3, MEMORY. Verifiche IA: `php -l` OK, msgfmt OK, git diff OK. **NESSUN bump versione** (regola 6: non tocca schemi DB del plugin). La pulizia si attiva in UI solo alla disinstallazione (azione utente, regola 7). + +## TODO / BLOCKED (da sbloccare su PROD/SEMI-PROD — richiede output utente) +1. **Crash globale dopo logoff su prod** (disins "uninstall" TOGLIE GLPI; riattivando il plugin torna tutto funzionante). NON riproducibile localmente, codice locale sano. Serve da prod/semi-prod: + - `find plugins/urbackup/src plugins/urbackup/front plugins/urbackup/install -name "*.php" -exec php -l {} \; | grep -v "No syntax errors"` + - `tail -100 files/_log/php-errors.log` + `tail -100 files/_log/php.log` (+ log Apache/PHP-FPM) +2. **Log client mancanti su semi-prod/prod** (locali OK su localhost:55414). Fattore più probabile: verificare che l'utente API UrBackup usato dal plugin abbia il diritto **`logs`** (scope `all` o per client) — fonte backend `livelog.cpp:117-122` (i log per-client sono restituiti SOLO se l'utente API ha il diritto logs con scope all/attinente). Il parametro `clientid` è CORRETTO (confermato empiricamente + wrapper `_legacy.py:296-299` + `livelog.cpp:88-93`). ## 31/08/2026 — Rinominate le tab della scheda Server + grafica Missing (solo UI/testi) -- **Rinominazione tab** (`front/server.form.php:118,123,128`): "Linked clients"→**"Managed clients" / Clienti gestiti** (asset GLPI con agent installato e collegamento attivo); "Unlinked clients"→**"Linkable clients" / Clienti Collegabili** (asset con agent installato ma non collegato a un asset GLPI); "Missing clients"→**"Clients to manage" / Clienti da gestire** (asset GLPI nella sede del server SENZA agent installato — "Connect" crea il link ma va poi installato il client). Aggiornate le traduzioni it/de/en (`.po`+`.mo` ricompilati con msgfmt) e rimosse le vecchie stringhe "Linked/Unlinked/Missing clients" dal catalogo. +- **Rinominazione tab** (`front/server.form.php:118,123,128`): "Linked clients"→**"Managed clients" / Elementi gestiti (it)** (asset GLPI con agent installato e collegamento attivo); "Unlinked clients"→**"Linkable clients" / Elementi collegabili (it)** (asset con agent installato ma non collegato a un asset GLPI); "Missing clients"→**"Clients to manage" / Elementi da gestire (it)** (asset GLPI nella sede del server SENZA agent installato — "Connect" crea il link ma va poi installato il client). Aggiornate le traduzioni it/de/en (`.po`+`.mo` ricompilati con msgfmt) e rimosse le vecchie stringhe "Linked/Unlinked/Missing clients" dal catalogo. - **Grafica tab Missing** (`src/Server.php` `showMissingClientsTab`): rimossi il campo di ricerca `#missing-search`, gli header `class="sortable"`+`` (stile non definito in CSS), l'id `missing-table` e tutto il blocco JS ordinamento/filtro → la tabella ora usa lo stesso `` delle tab Linked/Unlinked. - **Redirect "Connect"** (`front/server.form.php:31`): dopo il link_asset la pagina riapre sulla scheda "Clienti non collegati" (Unlinked/Clients to manage) aggiungendo `#tab-unlinked` al redirect (il JS già presente riattiva la tab dall'hash). - Nessun bump versione (nessuna modifica DB, regola 6). Verifiche IA: `php -l` OK, msgfmt OK, git diff autorevisione OK. **Verifica UI utente OBBLIGATORIA**: controllare etichette traduczione, grafica Missing uniforme, redirect su scheda corretta. @@ -292,6 +304,7 @@ La colonna `users_id` non esisteva nella tabella `glpi_plugin_urbackup_servers`. 2. **Form server**: riga "Hardware host" con dropdown tipo (`Dropdown::showItemTypes`) + dropdown elementi AJAX (`$.get` su `front/dropdown_host.ajax.php`, vedi sezione Fix del 07/08/2026). 3. **AssetTab**: blocco "This asset hosts the UrBackup server" (sempre visibile, anche se client). 4. **Validazione** in `prepareInputForUpdate()` + helper `getHostAsset()` / `getServersHostingAsset()` (guard `fieldExists`). +5. **Pulizia capacity all'uninstall**: `plugin_urbackup_uninstall_cleanup_capacities()` in `install/uninstall.php` rimuove il riferimento `GlpiPlugin\Urbackup\Capacity\UrBackupCapacity` dalla colonna JSON `capacities` di `glpi_assetdefinitions` (il core GLPI ignora in sicurezza tali capacity orfane via `decodeCapacities()`/`AssetDefinition.php:698-701`, ma ora vengono pulite). Nuova stringa i18n "UrBackup capacity removed from asset definitions" (it/de/en, `.mo` ricompilati). NESSUN bump di versione (non tocca schemi DB del plugin). ## 0.7.2 — Toggle Computer configurabile + lista Asset custom con capacità attiva 1. **`enable_computer` in `glpi_plugin_urbackup_configs`** (default '1') letto da `Config::getEnableComputer()`; registrazione tab su Computer condizionale in setup.php; `isItemtypeEnabled`/`getEnabledItemtypes` rispettano il toggle. diff --git a/README.md b/README.md index 258dd3d..e645837 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ plugin_urbackup/ - Made the missing/unlinked clients queries server-scoped (`plugin_urbackup_servers_id`) and the API data session cache key unique per asset (itemtype+id) - `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 +- **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) ### 0.7.2 - UrBackup on Computer is now configurable: new `enable_computer` setting on the plugin configuration page (previously always enabled, hardcoded) diff --git a/install/uninstall.php b/install/uninstall.php index dcd455d..9b47cee 100644 --- a/install/uninstall.php +++ b/install/uninstall.php @@ -16,6 +16,49 @@ if (!defined('GLPI_ROOT')) { require_once __DIR__ . '/install.php'; +/** + * Remove the UrBackup capacity reference from Asset Definitions. + * + * When the plugin is uninstalled, the `UrBackupCapacity` class no longer exists, + * but its reference may remain stored in the `capacities` JSON column of + * `glpi_assetdefinitions`. GLPI core safely ignores such orphaned capacities, + * but we clean them up so the database does not keep stale references. + * + * @param Migration $migration Migration instance + * + * @return void + */ +function plugin_urbackup_uninstall_cleanup_capacities(Migration $migration, \DBmysql $db): void +{ + $capacity_class = \GlpiPlugin\Urbackup\Capacity\UrBackupCapacity::class; + $table = 'glpi_assetdefinitions'; + + if (!$db->tableExists($table)) { + return; + } + + foreach ($db->request(['FROM' => $table, 'WHERE' => ['capacities' => ['<>' => '[]']]]) as $row) { + $decoded = json_decode((string) $row['capacities'], true); + if (!is_array($decoded)) { + continue; + } + + $filtered = array_values(array_filter($decoded, static function ($spec) use ($capacity_class): bool { + return is_array($spec) && (string) ($spec['name'] ?? '') !== $capacity_class; + })); + + if (count($filtered) === count($decoded)) { + continue; + } + + $db->update($table, [ + 'capacities' => json_encode($filtered), + ], ['id' => (int) $row['id']]); + } + + $migration->displayMessage(__('UrBackup capacity removed from asset definitions', 'urbackup')); +} + /** * Uninstall plugin. * @@ -29,6 +72,9 @@ function plugin_urbackup_uninstall_process(): bool Profile::uninstallRights(); + global $DB; + plugin_urbackup_uninstall_cleanup_capacities($migration, $DB); + plugin_urbackup_migration_drop_table($migration, 'glpi_plugin_urbackup_profiles'); plugin_urbackup_migration_drop_table($migration, 'glpi_plugin_urbackup_serverassets'); plugin_urbackup_migration_drop_table($migration, 'glpi_plugin_urbackup_servers'); diff --git a/locales/de_DE.mo b/locales/de_DE.mo index e91829f..ae9cd99 100644 Binary files a/locales/de_DE.mo and b/locales/de_DE.mo differ diff --git a/locales/de_DE.po b/locales/de_DE.po index be13f82..b6bb695 100644 --- a/locales/de_DE.po +++ b/locales/de_DE.po @@ -532,6 +532,9 @@ msgstr "" "Die UrBackup-API gab eine Nicht-JSON-Antwort (HTML) zurück. Server-URL und " "Authentifizierung prüfen." +msgid "UrBackup capacity removed from asset definitions" +msgstr "UrBackup-Kapazität aus Asset-Definitionen entfernt" + msgid "UrBackup Servers" msgstr "UrBackup-Server" diff --git a/locales/en_GB.mo b/locales/en_GB.mo index 40d6a26..f0fa479 100644 Binary files a/locales/en_GB.mo and b/locales/en_GB.mo differ diff --git a/locales/en_GB.po b/locales/en_GB.po index d4c8b38..acf4b48 100644 --- a/locales/en_GB.po +++ b/locales/en_GB.po @@ -524,6 +524,9 @@ msgstr "" "UrBackup API returned non-JSON response (HTML). Check server URL and " "authentication." +msgid "UrBackup capacity removed from asset definitions" +msgstr "UrBackup capacity removed from asset definitions" + msgid "UrBackup Servers" msgstr "UrBackup Servers" diff --git a/locales/it_IT.mo b/locales/it_IT.mo index 27c8e2a..b175811 100644 Binary files a/locales/it_IT.mo and b/locales/it_IT.mo differ diff --git a/locales/it_IT.po b/locales/it_IT.po index b6f70a1..5f286fe 100644 --- a/locales/it_IT.po +++ b/locales/it_IT.po @@ -307,7 +307,7 @@ msgid "Linked assets" msgstr "Asset collegati" msgid "Managed clients" -msgstr "Clienti gestiti" +msgstr "Elementi gestiti" msgid "Linked server" msgstr "Server collegato" @@ -325,7 +325,7 @@ msgid "Method not allowed" msgstr "Metodo non consentito" msgid "Clients to manage" -msgstr "Clienti da gestire" +msgstr "Elementi da gestire" msgid "Name" msgstr "Nome" @@ -506,7 +506,7 @@ msgid "Unknown" msgstr "Sconosciuto" msgid "Linkable clients" -msgstr "Clienti Collegabili" +msgstr "Elementi collegabili" msgid "Update" msgstr "Aggiorna" @@ -533,6 +533,9 @@ msgstr "" "L'API UrBackup ha restituito una risposta non-JSON (HTML). Controllare URL " "del server e autenticazione." +msgid "UrBackup capacity removed from asset definitions" +msgstr "Capacità UrBackup rimossa dalle definizioni di asset" + msgid "UrBackup Servers" msgstr "Server UrBackup" diff --git a/src/Server.php b/src/Server.php index 1ef6032..0f78cb2 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1374,6 +1374,7 @@ class Server extends CommonDBTM $formAction = PLUGIN_URBACKUP_WEB_DIR . '/front/server.form.php'; + echo '
'; echo '
'; echo ''; echo ''; @@ -1430,6 +1431,7 @@ class Server extends CommonDBTM echo ''; echo '
' . htmlspecialchars(__('Name')) . '
'; + echo ''; } private static function getCachedName(string $classname, int $id, array &$cache): string