displayMessage(__('UrBackup plugin installation', 'urbackup')); plugin_urbackup_install_create_initial_schema($migration); plugin_urbackup_install_update_configs_table($migration); // Convert old assettype configurations to GLPI 11 capacity system plugin_urbackup_install_convert_assettypes_to_capacities($migration); plugin_urbackup_install_update_servers_table($migration); plugin_urbackup_install_update_serverassets_table($migration); plugin_urbackup_install_encrypt_api_passwords(); plugin_urbackup_install_add_enable_computer_config(); // Drop tables that are no longer used (replaced by Profile::registerRights() and Capacity system) plugin_urbackup_install_drop_legacy_tables($migration); $migration->executeMigration(); Profile::installRights(); return true; } /** * Create initial database schema from SQL file. * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_create_initial_schema(Migration $migration): void { global $DB; $required_tables = [ 'glpi_plugin_urbackup_configs', 'glpi_plugin_urbackup_servers', 'glpi_plugin_urbackup_serverassets', ]; $missing_table_found = false; foreach ($required_tables as $table) { if (!$DB->tableExists($table)) { $missing_table_found = true; break; } } if (!$missing_table_found) { return; } $migration->displayMessage(__('Creating UrBackup plugin database schema', 'urbackup')); $db_file = PLUGIN_URBACKUP_DIR . '/install/mysql/plugin_urbackup-empty.sql'; if (!file_exists($db_file)) { $migration->displayMessage( sprintf( __('Database schema file not found: %s', 'urbackup'), $db_file ) ); return; } if (!$DB->runFile($db_file)) { $migration->displayMessage(__('Error while creating UrBackup plugin database schema', 'urbackup')); } } /** * Update configs table. * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_update_configs_table(Migration $migration): void { global $DB; $table = 'glpi_plugin_urbackup_configs'; if (!$DB->tableExists($table)) { return; } $migration->addField($table, 'name', 'string', [ 'value' => '', 'after' => 'id', ]); $migration->addField($table, 'value', 'text', [ 'after' => 'name', ]); $migration->addField($table, 'date_creation', 'timestamp'); $migration->addField($table, 'date_mod', 'timestamp'); $migration->addKey($table, 'name'); } /** * Update servers table. * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_update_servers_table(Migration $migration): void { global $DB; $table = 'glpi_plugin_urbackup_servers'; if (!$DB->tableExists($table)) { return; } $migration->addField($table, 'entities_id', 'integer', [ 'value' => 0, 'after' => 'id', ]); $migration->addField($table, 'is_recursive', 'bool', [ 'value' => 0, 'after' => 'entities_id', ]); $migration->addField($table, 'name', 'string', [ 'value' => '', 'after' => 'is_recursive', ]); $migration->addField($table, 'locations_id', 'integer', [ 'value' => 0, 'after' => 'name', ]); $migration->addField($table, 'users_id', 'integer', [ 'value' => 0, 'after' => 'locations_id', ]); $migration->addField($table, 'ip_address', 'string', [ 'value' => '', 'after' => 'locations_id', ]); $migration->addField($table, 'port', 'integer', [ 'value' => 55414, 'after' => 'ip_address', ]); $migration->addField($table, 'protocol', 'string', [ 'value' => 'http', 'after' => 'port', ]); $migration->addField($table, 'server_version', 'string', [ 'after' => 'protocol', ]); $migration->addField($table, 'api_username', 'string', [ 'after' => 'server_version', ]); $migration->addField($table, 'api_password', 'text', [ 'after' => 'api_username', ]); $migration->addField($table, 'ignore_ssl', 'bool', [ 'value' => 0, 'after' => 'api_password', ]); $migration->addField($table, 'is_active', 'bool', [ 'value' => 1, 'after' => 'ignore_ssl', ]); $migration->addField($table, 'last_api_status', 'bool', [ 'value' => 0, 'after' => 'is_active', ]); $migration->addField($table, 'last_api_message', 'text', [ 'after' => 'last_api_status', ]); $migration->addField($table, 'last_api_check', 'timestamp', [ 'after' => 'last_api_message', ]); $migration->addField($table, 'comment', 'text', [ 'after' => 'last_api_check', ]); $migration->addField($table, 'host_itemtype', 'string', [ 'after' => 'comment', ]); $migration->addField($table, 'host_items_id', 'integer', [ 'value' => 0, 'after' => 'host_itemtype', ]); $migration->addField($table, 'date_creation', 'timestamp'); $migration->addField($table, 'date_mod', 'timestamp'); $migration->addKey($table, 'name'); $migration->addKey($table, 'entities_id'); $migration->addKey($table, 'locations_id'); $migration->addKey($table, 'users_id'); $migration->addKey($table, 'is_active'); $migration->addKey($table, ['locations_id', 'is_active'], 'location_active'); $migration->addKey($table, ['host_itemtype', 'host_items_id'], 'host_asset'); } /** * Update serverassets table. * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_update_serverassets_table(Migration $migration): void { global $DB; $table = 'glpi_plugin_urbackup_serverassets'; if (!$DB->tableExists($table)) { return; } $migration->addField($table, 'plugin_urbackup_servers_id', 'integer', [ 'value' => 0, 'after' => 'id', ]); $migration->addField($table, 'itemtype', 'string', [ 'value' => '', 'after' => 'plugin_urbackup_servers_id', ]); $migration->addField($table, 'items_id', 'integer', [ 'value' => 0, 'after' => 'itemtype', ]); $migration->addField($table, 'date_creation', 'timestamp'); $migration->addField($table, 'date_mod', 'timestamp'); $migration->addKey($table, 'plugin_urbackup_servers_id'); $migration->addKey($table, ['itemtype', 'items_id'], 'item'); } /** * Encrypt api_password values still stored in plaintext. * * Runs on every install/update, but skips values that already use the * GLPIKey encrypted format (idempotent). If the GLPI key is unavailable, * the plaintext value is kept to avoid data loss. * * @return void */ function plugin_urbackup_install_encrypt_api_passwords(): void { global $DB; $table = 'glpi_plugin_urbackup_servers'; if (!$DB->tableExists($table)) { return; } $iterator = $DB->request([ 'FROM' => $table, 'WHERE' => ['api_password' => ['<>', '']], ]); foreach ($iterator as $row) { $password = (string) $row['api_password']; if ($password === '' || Server::isApiPasswordEncrypted($password)) { continue; } $encrypted = (new GLPIKey())->encrypt($password); if ($encrypted === '') { continue; } $DB->update( $table, ['api_password' => $encrypted], ['id' => (int) $row['id']] ); } } /** * Ensure the `enable_computer` config row exists (default: enabled). * * Computer is registered as a plain tab (not a capacity), so its default * state must be stored in the config table to keep it backward compatible * with previous versions where Computer was always enabled. Idempotent. * * @return void */ function plugin_urbackup_install_add_enable_computer_config(): void { global $DB; $table = 'glpi_plugin_urbackup_configs'; if (!$DB->tableExists($table)) { return; } $iterator = $DB->request([ 'FROM' => $table, 'WHERE' => ['name' => 'enable_computer'], ]); if (count($iterator) > 0) { return; } $DB->insert($table, [ 'name' => 'enable_computer', 'value' => '1', 'date_creation' => $_SESSION['glpi_currenttime'] ?? date('Y-m-d H:i:s'), ]); } /** * Drop a plugin table through Migration. * * Shared helper used by both install and uninstall processes * (uninstall.php requires install.php to get this function). * * @param Migration $migration Migration instance * @param string $table Table name * * @return void */ function plugin_urbackup_migration_drop_table(Migration $migration, string $table): void { global $DB; if (!$DB->tableExists($table)) { return; } $migration->dropTable($table); } /** * Drop legacy tables that are no longer used. * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_drop_legacy_tables(Migration $migration): void { global $DB; // glpi_plugin_urbackup_profiles was replaced by Profile::registerRights() in 0.5.0 plugin_urbackup_migration_drop_table($migration, 'glpi_plugin_urbackup_profiles'); // glpi_plugin_urbackup_assettypes was replaced by GLPI 11 Capacity system in 0.6.0 plugin_urbackup_migration_drop_table($migration, 'glpi_plugin_urbackup_assettypes'); } /** * Convert old glpi_plugin_urbackup_assettypes to GLPI 11 capacity system. * * The legacy table is only kept to drop the obsolete `is_default` column. * Enabling/disabling the UrBackup capacity on Asset Definitions is done by * the admin via the native Capacities UI (Config > Asset definitions > * Capacities). GLPI 11.0.x provides no public API to programmatically enable * a capacity (it is processed from the `capacities` form input in * AssetDefinition::post_updateItem()). * * @param Migration $migration Migration instance * * @return void */ function plugin_urbackup_install_convert_assettypes_to_capacities(Migration $migration): void { global $DB; $table = Config::getAssetTypesTable(); if (!$DB->tableExists($table)) { return; } // Check if is_default column exists $has_is_default = false; foreach ($DB->listFields($table) as $col) { if ($col['Field'] === 'is_default') { $has_is_default = true; break; } } // Drop is_default column (no longer needed in capacity system) if ($has_is_default) { $migration->dropField($table, 'is_default'); } }