# MEMORY.md - Stato del Plugin UrBackup ## Ultima modifica: 28/05/2026 ## GLPI 11 — Session::checkCSRF() breaking change In GLPI 11, `Session::checkCSRF()` richiede il primo argomento `$data` (i dati POST da validare). In GLPI ≤10 accettava zero argomenti. Il listener globale `CheckCsrfListener` gestisce già il CSRF per tutte le richieste POST, ma il plugin chiamava `Session::checkCSRF()` senza argomenti causando errore fatale. ### Fix applicati (tutti i file) - RIMOSSE tutte le chiamate esplicite `Session::checkCSRF()` dai 4 file front — GLPI 11 le gestisce già globalmente via `CheckCsrfListener` - Il listener globale consuma il token CSRF, quindi una seconda chiamata dal plugin fallisce perché il token non è più valido - `public/js/urbackup.js` — aggiunto header `X-Glpi-Csrf-Token` con `getAjaxCsrfToken()` per le richieste AJAX ## Performance - Asset Definition vs Computer ### Problema Gli Asset Definition custom (GLPI 11) sono 2-5x più lenti dei Computer nativi nel caricamento del tab UrBackup. ### Causa L'overhead è in GLPI 11 core, non nel plugin: 1. **`Asset::__construct()`** — itera 30+ Capacity classi per ogni istanza 2. **`Asset::post_getFromDB()`** — decodifica JSON custom fields e li processa 3. **`eval()` autoloading** — le classi concrete sono definite via `eval()` a runtime ### Ottimizzazioni applicate 1. **`AssetTab.php::loadApiData()`** — letto `$item->fields['name']` direttamente invece di chiamare `ServerAsset::getAssetName()` che faceva una seconda `getFromDB()` ridondante 2. **`AssetTab.php::startBackup()`, `saveInternetMode()`, `saveDefaultDirs()`, `showServerLinkedBlock()`** — stesso pattern, `$item->fields['name']` al posto di `getAssetName()` 3. **`Server.php::showMissingClientsTab()`** — batch loading IP e gruppi: `batchLoadIps()` (1 query per itemtype vs 1 per riga) + `batchLoadGroups()` (1 query per itemtype vs 1 per riga) ## Architettura - `src/Capacity/UrBackupCapacity.php` — registra `AssetTab` via `CommonGLPI::registerStandardTab()` in `onClassBootstrap()` - `setup.php` — registra capacità, CSS, JS, hook - `src/AssetTab.php` — display tab content + tab interni (Stato/Azioni/Info-Log) - `src/ServerAsset.php` — gestione collegamenti asset-server - `src/Config.php` — itemtype enabled check - `src/UrbackupApiClient.php` — client API con caching in-memory (per istanza) e sessione - `src/LocationHelper.php` — risoluzione location radice - `src/Server.php` — CRUD server, tab missing clients, form ## Asset Tab Interni - 3 sub-tab: Stato, Azioni (solo UPDATE/CREATE), Info/Log - CSS: tab con tonalità di grigio differenti (scuro/medio/chiaro) - Caricamento dati API con caching sessione 30s - Dati caricati: status, settings, authkey, backup recenti (10), log (50) ## Cache - `UrbackupApiClient`: cache in-memory per `getStatus()` e `getClientSettings()` - `AssetTab::loadApiData()`: cache sessione 30s (chiave: server_id + client_name) - API timeout: 30s, connect timeout: 5s ## Bugfix: Campi API username/password non visibili in nuova installazione ### Problema In una nuova installazione del plugin, i campi "API username" e "API password" non venivano renderizzati come input — si vedeva solo la label ma non il campo editabile. ### Cause (2 bug distinti) 1. **`src/Server.php:436`** — `$canUpdate` controllava solo `Session::haveRight(self::$rightname, UPDATE)`. In fase di creazione di un nuovo server, l'utente ha diritto CREATE ma non necessariamente UPDATE, quindi il campo non veniva mostrato. 2. **`src/Profile.php:73-77`** — `installRights()` usava `$_SESSION['glpiactiveprofile']['id']` per assegnare i diritti completi al profilo corrente. In installazione via CLI (`php bin/console glpi:plugin:install`), non c'è sessione, quindi `$profiles_id = 0` e nessun profilo riceveva i diritti completi. ### Fix applicati 1. **`Server.php::showFormFields()`** — Sostituito `$canUpdate` con `$canEdit`: per nuovi server (`$ID <= 0`) usa `CREATE`, per server esistenti usa `UPDATE`. 2. **`Profile.php::installRights()`** — In assenza di sessione attiva (CLI), cerca il profilo "Super-Admin" tramite query diretta e gli assegna tutti i diritti. ## Versione - 0.7.0 ## 0.7.0 — Pulizia, sicurezza e DB cleanup 1. **CSRF hardening**: `Session::checkCSRF()` aggiunto su `asset.form.php`, `server.form.php`, `server_test.ajax.php`, `config.form.php` 2. **File deprecati rimossi**: 12 file (composer copy, AGENTS_OLD.MD, js/, ajax/, front/test/view, FIX_PERMISSIONS.sh, removed/) 3. **Dead code rimosso**: 3 Controller, 1 Command, 4 template Twig 4. **DB migration**: DROP `glpi_plugin_urbackup_profiles` e `glpi_plugin_urbackup_assettypes`; add index `location_active` su servers; add `date_creation`/`date_mod` su serverassets 5. **SQL schema pulito**: Rimosse tabelle legacy dall'empty.sql 6. **PHP lint warnings**: Rimosse `use Html;` e `use Search;` superflue 7. **README.md** creato 8. **PURGE right**: Aggiunto PURGE ai diritti di installazione (`Profile.php:76,90`); applicato a tutti i profili Super-Admin esistenti nel DB 9. **CSRF GLPI 11 fix**: `Session::checkCSRF()` richiede `$_POST` come argomento in GLPI 11; aggiunto `X-Glpi-Csrf-Token` header al JS AJAX