gestione assets

This commit is contained in:
mariano
2026-05-22 08:29:59 +02:00
parent f7c1ab8aa4
commit 13cb325576
11 changed files with 391 additions and 627 deletions
+6 -2
View File
@@ -57,11 +57,15 @@ class AssetTab extends CommonDBTM
*/
public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0): string
{
if (!Config::isItemtypeEnabled($item::class)) {
$itemtype = $item::class;
$enabled = Config::isItemtypeEnabled($itemtype);
$hasRight = Profile::canCurrentUser(READ);
if (!$enabled) {
return '';
}
if (!Profile::canCurrentUser(READ)) {
if (!$hasRight) {
return '';
}
+62
View File
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace GlpiPlugin\Urbackup\Capacity;
use CommonGLPI;
use Glpi\Asset\Capacity\AbstractCapacity;
use Glpi\Asset\CapacityConfig;
use GlpiPlugin\Urbackup\AssetTab;
use GlpiPlugin\Urbackup\Server;
use GlpiPlugin\Urbackup\ServerAsset;
final class UrBackupCapacity extends AbstractCapacity
{
public function getLabel(): string
{
return __('UrBackup', 'urbackup');
}
public function getIcon(): string
{
return 'ti ti-cloud-up';
}
public function getDescription(): string
{
return __('Manage UrBackup backups for these assets', 'urbackup');
}
public function onClassBootstrap(string $classname, CapacityConfig $config): void
{
CommonGLPI::registerStandardTab($classname, AssetTab::class);
}
public function onCapacityDisabled(string $classname, CapacityConfig $config): void
{
(new ServerAsset())->deleteByCriteria(
['itemtype' => $classname],
force: true,
history: false
);
$this->deleteRelationLogs($classname, Server::class);
}
public function isUsed(string $classname): bool
{
return parent::isUsed($classname)
&& $this->countAssetsLinkedToPeerItem(
$classname,
ServerAsset::class
) > 0;
}
public function getCapacityUsageDescription(string $classname): string
{
return sprintf(
__('%1$s assets linked to UrBackup servers', 'urbackup'),
$this->countAssetsLinkedToPeerItem($classname, ServerAsset::class)
);
}
}
+33 -282
View File
@@ -11,8 +11,7 @@ declare(strict_types=1);
namespace GlpiPlugin\Urbackup;
use CommonDBTM;
use Computer;
use Glpi\Asset\AssetDefinition;
use Glpi\Asset\Asset;
use Glpi\Asset\AssetDefinitionManager;
use DBmysql;
use Html;
@@ -53,67 +52,8 @@ class Config extends CommonDBTM
*/
public static function ensureDefaultConfiguration(): void
{
self::ensureAssetType('Computer', true, true);
}
/**
* Ensure an asset type is registered.
*
* @param string $itemtype Itemtype
* @param bool $is_active Active
* @param bool $is_default Default
*
* @return void
*/
public static function ensureAssetType(
string $itemtype,
bool $is_active = true,
bool $is_default = false
): void {
global $DB;
$table = self::getAssetTypesTable();
if (!$DB->tableExists($table)) {
return;
}
$existing = $DB->request([
'FROM' => $table,
'WHERE' => [
'itemtype' => $itemtype,
],
'LIMIT' => 1,
]);
if (count($existing) > 0) {
$row = $existing->current();
$DB->update(
$table,
[
'is_active' => $is_active ? 1 : 0,
'is_default' => $is_default ? 1 : 0,
'date_mod' => $_SESSION['glpi_currenttime'] ?? date('Y-m-d H:i:s'),
],
[
'id' => (int) $row['id'],
]
);
return;
}
$DB->insert(
$table,
[
'itemtype' => $itemtype,
'is_active' => $is_active ? 1 : 0,
'is_default' => $is_default ? 1 : 0,
'date_creation' => $_SESSION['glpi_currenttime'] ?? date('Y-m-d H:i:s'),
'date_mod' => $_SESSION['glpi_currenttime'] ?? date('Y-m-d H:i:s'),
]
);
// Computer is always enabled by default.
// Asset Definition types are managed via the native Capacities UI.
}
/**
@@ -135,8 +75,6 @@ class Config extends CommonDBTM
*/
public static function isItemtypeEnabled(string $itemtype): bool
{
global $DB;
if ($itemtype === '') {
return false;
}
@@ -145,22 +83,15 @@ class Config extends CommonDBTM
return true;
}
$table = self::getAssetTypesTable();
if (!$DB->tableExists($table)) {
return false;
// All Asset subclasses are enabled by default.
// The UrBackupCapacity is still registered for cleanup (onCapacityDisabled)
// and usage tracking in the Capacities UI, but visibility is always on
// so the tab appears out of the box on any Asset Definition.
if (is_a($itemtype, Asset::class, true)) {
return true;
}
$iterator = $DB->request([
'FROM' => $table,
'WHERE' => [
'itemtype' => $itemtype,
'is_active' => 1,
],
'LIMIT' => 1,
]);
return count($iterator) > 0;
return false;
}
/**
@@ -170,54 +101,19 @@ class Config extends CommonDBTM
*/
public static function getEnabledItemtypes(): array
{
global $DB;
$itemtypes = ['Computer'];
$types = ['Computer'];
$table = self::getAssetTypesTable();
if (!$DB->tableExists($table)) {
return $types;
}
$iterator = $DB->request([
'FROM' => $table,
'WHERE' => [
'is_active' => 1,
],
'ORDER' => 'itemtype',
]);
foreach ($iterator as $row) {
$itemtype = (string) $row['itemtype'];
if ($itemtype !== '' && !in_array($itemtype, $types, true)) {
$types[] = $itemtype;
if (class_exists(AssetDefinitionManager::class)) {
$manager = AssetDefinitionManager::getInstance();
foreach ($manager->getDefinitions() as $definition) {
$classname = $definition->getAssetClassName();
if (!in_array($classname, $itemtypes, true)) {
$itemtypes[] = $classname;
}
}
}
return $types;
}
/**
* Register tabs on enabled asset types.
*
* @return void
*/
public static function registerAssetTabs(): void
{
foreach (self::getEnabledItemtypes() as $itemtype) {
if (!class_exists($itemtype)) {
continue;
}
if (!is_a($itemtype, CommonDBTM::class, true)) {
continue;
}
\Plugin::registerClass(AssetTab::class, [
'addtabon' => $itemtype,
]);
}
return $itemtypes;
}
/**
@@ -232,71 +128,22 @@ class Config extends CommonDBTM
{
Session::checkRight('config', UPDATE);
echo "<form method='post' action='" . htmlspecialchars($options['target'] ?? '') . "'>";
echo "<div class='center'>";
echo "<table class='tab_cadre_fixe'>";
echo "<tr><th colspan='4'>" . htmlspecialchars(__('UrBackup configuration', 'urbackup')) . "</th></tr>";
echo "<tr>";
echo "<th>" . htmlspecialchars(__('Asset type', 'urbackup')) . "</th>";
echo "<th>" . htmlspecialchars(__('Enabled', 'urbackup')) . "</th>";
echo "<th>" . htmlspecialchars(__('Default', 'urbackup')) . "</th>";
echo "<th>" . htmlspecialchars(__('Type', 'urbackup')) . "</th>";
echo "<tr><th colspan='2'>" . htmlspecialchars(__('UrBackup configuration', 'urbackup')) . "</th></tr>";
echo "<tr class='tab_bg_1'>";
echo "<td><strong>" . htmlspecialchars(__('Computer', 'urbackup')) . "</strong></td>";
echo "<td><span class='badge bg-success'>" . htmlspecialchars(__('Always enabled', 'urbackup')) . "</span></td>";
echo "</tr>";
foreach (self::getConfigurableAssetTypes() as $itemtype => $label) {
$enabled = self::isItemtypeEnabled($itemtype);
$is_default = ($itemtype === 'Computer');
$is_asset_definition = self::isAssetDefinition($itemtype);
echo "<tr class='tab_bg_1'>";
echo "<td>" . htmlspecialchars($label) . "</td>";
if ($itemtype === 'Computer') {
echo "<td>" . htmlspecialchars(__('Always', 'urbackup')) . "</td>";
echo "<td>" . htmlspecialchars(__('Yes', 'urbackup')) . "</td>";
} elseif ($is_asset_definition) {
// GLPI 11 Asset Definition
echo "<td>";
Html::showCheckbox([
'name' => 'assettypes[' . htmlspecialchars($itemtype) . '][is_active]',
'checked' => $enabled,
]);
echo "</td>";
echo "<td>";
Html::showCheckbox([
'name' => 'assettypes[' . htmlspecialchars($itemtype) . '][is_default]',
'checked' => $is_default,
]);
echo "</td>";
echo "<td><span class='badge bg-info'>" . htmlspecialchars(__('Asset Definition', 'urbackup')) . "</span></td>";
} else {
// Legacy type
echo "<td>";
Html::showCheckbox([
'name' => 'assettypes[' . htmlspecialchars($itemtype) . ']',
'checked' => $enabled,
]);
echo "</td>";
echo "<td>" . ($is_default ? htmlspecialchars(__('Yes', 'urbackup')) : '') . "</td>";
echo "<td><span class='badge bg-secondary'>" . htmlspecialchars(__('Legacy', 'urbackup')) . "</span></td>";
}
echo "</tr>";
}
echo "<tr>";
echo "<td colspan='4' class='center'>";
echo Html::submit(__('Save', 'urbackup'), [
'name' => 'update',
'class' => 'btn btn-primary',
]);
echo "</td>";
echo "</tr>";
echo "</table>";
echo "</div>";
Html::closeForm();
echo "<br>";
echo "<div class='alert alert-info'>";
echo htmlspecialchars(
__('For Asset Definition types, enable/disable UrBackup via Config > Asset definitions > Capacities.', 'urbackup')
);
echo "</div>";
echo "</div>";
return true;
}
@@ -304,6 +151,9 @@ class Config extends CommonDBTM
/**
* Save configuration.
*
* In the new capacity system, asset types are managed via the native Capacities UI.
* This method is kept for backward compatibility but does nothing.
*
* @param array<string, mixed> $input Input data
*
* @return void
@@ -311,104 +161,5 @@ class Config extends CommonDBTM
public static function saveConfiguration(array $input): void
{
Session::checkRight('config', UPDATE);
$selected = $input['assettypes'] ?? [];
foreach (self::getConfigurableAssetTypes() as $itemtype => $label) {
if ($itemtype === 'Computer') {
self::ensureAssetType('Computer', true, true);
continue;
}
// Check if it's an Asset Definition (new format with is_active/is_default)
if (self::isAssetDefinition($itemtype)) {
$is_active = isset($selected[$itemtype]['is_active']) && (bool) $selected[$itemtype]['is_active'];
$is_default = isset($selected[$itemtype]['is_default']) && (bool) $selected[$itemtype]['is_default'];
self::ensureAssetType($itemtype, $is_active, $is_default);
} else {
// Legacy format (simple checkbox)
$is_enabled = isset($selected[$itemtype]) && (bool) $selected[$itemtype];
self::ensureAssetType($itemtype, $is_enabled, false);
}
}
}
/**
* Get configurable asset types (legacy + GLPI 11 Asset Definition).
*
* @return array<string, string>
*/
public static function getConfigurableAssetTypes(): array
{
$types = [
'Computer' => Computer::getTypeName(Session::getPluralNumber()),
];
// Legacy types
$known_types = [
'Printer',
'Peripheral',
'NetworkEquipment',
'Phone',
'Monitor',
];
foreach ($known_types as $itemtype) {
if (!class_exists($itemtype)) {
continue;
}
if (!is_a($itemtype, CommonDBTM::class, true)) {
continue;
}
$types[$itemtype] = $itemtype::getTypeName(Session::getPluralNumber());
}
// GLPI 11 Asset Definition
if (class_exists(AssetDefinitionManager::class)) {
try {
$assetDefinitions = AssetDefinitionManager::getInstance()->getDefinitions(true);
foreach ($assetDefinitions as $definition) {
// Access fields directly like CommonDBTM
$system_name = $definition->fields['system_name'] ?? '';
$name = $definition->fields['name'] ?? '';
if (!empty($system_name)) {
$types[$system_name] = !empty($name) ? $name : $system_name;
}
}
} catch (\Throwable $e) {
// If AssetDefinitionManager fails, skip
}
}
return $types;
}
/**
* Check if itemtype is a GLPI 11 Asset Definition.
*
* @param string $itemtype Itemtype or system name
*
* @return bool
*/
public static function isAssetDefinition(string $itemtype): bool
{
if (!class_exists(AssetDefinitionManager::class)) {
return false;
}
try {
$assetDefinitions = AssetDefinitionManager::getInstance()->getDefinitions(true);
foreach ($assetDefinitions as $definition) {
if (($definition->fields['system_name'] ?? '') === $itemtype) {
return true;
}
}
} catch (\Throwable $e) {
// If fails, return false
}
return false;
}
}
+1 -10
View File
@@ -31,15 +31,6 @@ class ConfigController extends AbstractController
Html::back();
}
$configurableTypes = Config::getConfigurableAssetTypes();
$enabledTypes = [];
foreach ($configurableTypes as $itemtype => $label) {
$enabledTypes[$itemtype] = Config::isItemtypeEnabled($itemtype);
}
return $this->render('config/config.html.twig', [
'configurable_types' => $configurableTypes,
'enabled_types' => $enabledTypes,
]);
return $this->render('config/config.html.twig', []);
}
}
+4 -1
View File
@@ -27,7 +27,9 @@ class UrbackupApiClient
private bool $ignore_ssl;
private int $timeout = 10;
private int $timeout = 30;
private int $connect_timeout = 5;
private string $session = '';
@@ -667,6 +669,7 @@ class UrbackupApiClient
$options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_CONNECTTIMEOUT => $this->connect_timeout,
CURLOPT_SSL_VERIFYPEER => !$this->ignore_ssl,
CURLOPT_SSL_VERIFYHOST => $this->ignore_ssl ? 0 : 2,
CURLOPT_HTTPHEADER => [