2026-05-20 09:20:27 +02:00
|
|
|
<?php
|
|
|
|
|
|
2026-05-21 10:54:04 +02:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2026-05-20 09:20:27 +02:00
|
|
|
/**
|
|
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
|
* UrBackup plugin for GLPI
|
|
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
2026-05-22 08:29:59 +02:00
|
|
|
use Glpi\Asset\AssetDefinitionManager;
|
|
|
|
|
use GlpiPlugin\Urbackup\Capacity\UrBackupCapacity;
|
2026-05-20 09:20:27 +02:00
|
|
|
use GlpiPlugin\Urbackup\Config;
|
|
|
|
|
use GlpiPlugin\Urbackup\Profile;
|
|
|
|
|
|
|
|
|
|
if (!defined('GLPI_ROOT')) {
|
2026-05-21 11:08:15 +02:00
|
|
|
die(__('Sorry. You cannot access this file directly.', 'urbackup'));
|
2026-05-20 09:20:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Install or update plugin database schema and default data.
|
|
|
|
|
*
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function plugin_urbackup_install_process(): bool
|
|
|
|
|
{
|
|
|
|
|
$migration = new Migration(PLUGIN_URBACKUP_VERSION);
|
|
|
|
|
|
|
|
|
|
$migration->displayMessage(__('UrBackup plugin installation', 'urbackup'));
|
|
|
|
|
|
|
|
|
|
plugin_urbackup_install_create_initial_schema($migration);
|
|
|
|
|
|
|
|
|
|
plugin_urbackup_install_update_configs_table($migration);
|
2026-05-22 08:29:59 +02:00
|
|
|
|
|
|
|
|
// Convert old assettype configurations to GLPI 11 capacity system
|
|
|
|
|
plugin_urbackup_install_convert_assettypes_to_capacities($migration);
|
|
|
|
|
|
2026-05-20 09:20:27 +02:00
|
|
|
plugin_urbackup_install_update_servers_table($migration);
|
|
|
|
|
plugin_urbackup_install_update_serverassets_table($migration);
|
2026-05-28 11:57:47 +02:00
|
|
|
|
|
|
|
|
// Drop tables that are no longer used (replaced by Profile::registerRights() and Capacity system)
|
|
|
|
|
plugin_urbackup_install_drop_legacy_tables($migration);
|
2026-05-20 09:20:27 +02:00
|
|
|
|
|
|
|
|
$migration->executeMigration();
|
|
|
|
|
|
|
|
|
|
Config::ensureDefaultConfiguration();
|
|
|
|
|
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 assettypes table.
|
|
|
|
|
*
|
|
|
|
|
* @param Migration $migration Migration instance
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
function plugin_urbackup_install_update_assettypes_table(Migration $migration): void
|
|
|
|
|
{
|
|
|
|
|
global $DB;
|
|
|
|
|
|
|
|
|
|
$table = 'glpi_plugin_urbackup_assettypes';
|
|
|
|
|
|
|
|
|
|
if (!$DB->tableExists($table)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$migration->addField($table, 'itemtype', 'string', [
|
|
|
|
|
'value' => '',
|
|
|
|
|
'after' => 'id',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$migration->addField($table, 'is_active', 'bool', [
|
|
|
|
|
'value' => 0,
|
|
|
|
|
'after' => 'itemtype',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$migration->addField($table, 'date_creation', 'timestamp');
|
|
|
|
|
$migration->addField($table, 'date_mod', 'timestamp');
|
|
|
|
|
|
|
|
|
|
$migration->addKey($table, 'itemtype');
|
|
|
|
|
$migration->addKey($table, 'is_active');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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, '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, '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, 'is_active');
|
2026-05-28 11:57:47 +02:00
|
|
|
$migration->addKey($table, ['locations_id', 'is_active'], 'location_active');
|
2026-05-20 09:20:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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',
|
|
|
|
|
]);
|
|
|
|
|
|
2026-05-28 11:57:47 +02:00
|
|
|
$migration->addField($table, 'date_creation', 'timestamp');
|
|
|
|
|
$migration->addField($table, 'date_mod', 'timestamp');
|
|
|
|
|
|
2026-05-20 09:20:27 +02:00
|
|
|
$migration->addKey($table, 'plugin_urbackup_servers_id');
|
|
|
|
|
$migration->addKey($table, ['itemtype', 'items_id'], 'item');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-05-28 11:57:47 +02:00
|
|
|
* Drop legacy tables that are no longer used.
|
2026-05-20 09:20:27 +02:00
|
|
|
*
|
|
|
|
|
* @param Migration $migration Migration instance
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2026-05-28 11:57:47 +02:00
|
|
|
function plugin_urbackup_install_drop_legacy_tables(Migration $migration): void
|
2026-05-20 09:20:27 +02:00
|
|
|
{
|
|
|
|
|
global $DB;
|
|
|
|
|
|
2026-05-28 11:57:47 +02:00
|
|
|
// glpi_plugin_urbackup_profiles was replaced by Profile::registerRights() in 0.5.0
|
2026-05-20 09:20:27 +02:00
|
|
|
$table = 'glpi_plugin_urbackup_profiles';
|
2026-05-28 11:57:47 +02:00
|
|
|
if ($DB->tableExists($table)) {
|
|
|
|
|
$migration->displayMessage(__('Dropping legacy glpi_plugin_urbackup_profiles table', 'urbackup'));
|
|
|
|
|
$DB->queryOrDie("DROP TABLE IF EXISTS `$table`");
|
2026-05-20 09:20:27 +02:00
|
|
|
}
|
|
|
|
|
|
2026-05-28 11:57:47 +02:00
|
|
|
// glpi_plugin_urbackup_assettypes was replaced by GLPI 11 Capacity system in 0.6.0
|
|
|
|
|
$table2 = 'glpi_plugin_urbackup_assettypes';
|
|
|
|
|
if ($DB->tableExists($table2)) {
|
|
|
|
|
$migration->displayMessage(__('Dropping legacy glpi_plugin_urbackup_assettypes table', 'urbackup'));
|
|
|
|
|
$DB->queryOrDie("DROP TABLE IF EXISTS `$table2`");
|
|
|
|
|
}
|
2026-05-20 09:20:27 +02:00
|
|
|
|
2026-05-28 11:57:47 +02:00
|
|
|
$migration->displayMessage(__('Legacy tables dropped successfully', 'urbackup'));
|
2026-05-20 09:20:27 +02:00
|
|
|
}
|
2026-05-22 08:29:59 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Convert old glpi_plugin_urbackup_assettypes to GLPI 11 capacity system
|
|
|
|
|
* and auto-enable UrBackup capacity on all existing Asset Definitions.
|
|
|
|
|
*
|
|
|
|
|
* After this migration, admins can disable UrBackup per Asset Definition
|
|
|
|
|
* via the native Capacities UI (Config > Asset definitions > Capacities).
|
|
|
|
|
*
|
|
|
|
|
* @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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Auto-enable UrBackup capacity on ALL Asset Definitions
|
|
|
|
|
// so the tab appears out of the box for any asset type.
|
|
|
|
|
if (class_exists(AssetDefinitionManager::class)) {
|
|
|
|
|
try {
|
|
|
|
|
$manager = AssetDefinitionManager::getInstance();
|
|
|
|
|
foreach ($manager->getDefinitions() as $definition) {
|
|
|
|
|
if (!$definition->hasCapacity(UrBackupCapacity::class)) {
|
|
|
|
|
$definition->enableCapacity(UrBackupCapacity::class);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
$migration->displayMessage(
|
|
|
|
|
__('Error enabling UrBackup capacity on definitions: ', 'urbackup') . $e->getMessage()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Drop is_default column (no longer needed in capacity system)
|
|
|
|
|
if ($has_is_default) {
|
|
|
|
|
$migration->dropField($table, 'is_default');
|
|
|
|
|
}
|
|
|
|
|
}
|