';
- echo '| ' . htmlspecialchars($itemTypeLabel . ' #' . $link['items_id']) . ' | ';
- echo '' . ($itemUrl ? '' . htmlspecialchars($clientName) . '' : htmlspecialchars($clientName)) . ' | ';
+ echo '';
+ if ($itemUrl) {
+ echo '' . htmlspecialchars($clientName) . '';
+ } else {
+ echo htmlspecialchars($clientName);
+ }
+ echo ' (' . htmlspecialchars($itemTypeLabel) . ')';
+ echo ' | ';
echo '' . htmlspecialchars($urbackupClientName) . ' | ';
echo '' . htmlspecialchars($clientVersion) . ' | ';
echo '' . $statusHtml . ' | ';
@@ -1005,4 +1013,145 @@ $apiStatus = (int) ($this->fields['last_api_status'] ?? 0);
echo '';
echo '';
}
+
+ public static function showMissingClientsTab(Server $server): void
+ {
+ global $DB;
+
+ $apiStatus = (int) ($server->fields['last_api_status'] ?? 0);
+ if ($apiStatus !== 1) {
+ echo '';
+ echo htmlspecialchars(__('API connection not working. Save server to test connection.', 'urbackup'));
+ echo '
';
+ return;
+ }
+
+ $serverLocationId = (int) ($server->fields['locations_id'] ?? 0);
+ if ($serverLocationId <= 0) {
+ echo '';
+ echo htmlspecialchars(__('No location configured for this server.', 'urbackup'));
+ echo '
';
+ return;
+ }
+
+ $rootLocationId = LocationHelper::getRootLocationId($serverLocationId);
+
+ $linkedIterator = $DB->request([
+ 'FROM' => ServerAsset::getTable(),
+ ]);
+ $linkedAssetKeys = [];
+ foreach ($linkedIterator as $row) {
+ $linkedAssetKeys[$row['itemtype'] . ':' . $row['items_id']] = true;
+ }
+
+ try {
+ $client = new UrbackupApiClient($server);
+ $urbackupClients = $client->getStatus();
+ } catch (\Throwable $e) {
+ echo '';
+ echo htmlspecialchars($e->getMessage());
+ echo '
';
+ return;
+ }
+
+ $urbackupClientNames = [];
+ foreach ($urbackupClients as $uc) {
+ $name = strtolower((string) ($uc['name'] ?? $uc['clientname'] ?? $uc['hostname'] ?? ''));
+ if ($name !== '') {
+ $urbackupClientNames[$name] = true;
+ }
+ }
+
+ $itemtypes = Config::getEnabledItemtypes();
+ $missingAssets = [];
+
+ foreach ($itemtypes as $itemtype) {
+ if (!class_exists($itemtype)) {
+ continue;
+ }
+ $assetItem = new $itemtype();
+ if (!$assetItem instanceof CommonDBTM) {
+ continue;
+ }
+ $table = $assetItem->getTable();
+ if (!$DB->tableExists($table)) {
+ continue;
+ }
+
+ $iterator = $DB->request([
+ 'FROM' => $table,
+ 'WHERE' => [
+ 'is_deleted' => 0,
+ ],
+ ]);
+
+ foreach ($iterator as $assetRow) {
+ $name = (string) ($assetRow['name'] ?? '');
+ if ($name === '') {
+ continue;
+ }
+ $nameLower = strtolower($name);
+
+ $assetLocationId = (int) ($assetRow['locations_id'] ?? 0);
+ $assetRootLocationId = LocationHelper::getRootLocationId($assetLocationId);
+
+ if ($assetRootLocationId !== $rootLocationId) {
+ continue;
+ }
+
+ $key = $itemtype . ':' . $assetRow['id'];
+ if (isset($linkedAssetKeys[$key])) {
+ continue;
+ }
+ if (isset($urbackupClientNames[$nameLower])) {
+ continue;
+ }
+
+ $missingAssets[] = [
+ 'itemtype' => $itemtype,
+ 'items_id' => (int) $assetRow['id'],
+ 'name' => $name,
+ ];
+ }
+ }
+
+ if (count($missingAssets) === 0) {
+ echo '';
+ echo htmlspecialchars(__('All assets in this location are linked or already on the UrBackup server.', 'urbackup'));
+ echo '
';
+ return;
+ }
+
+ $formAction = PLUGIN_URBACKUP_WEB_DIR . '/front/server.form.php';
+
+ echo '';
+ echo '';
+ echo '| ' . htmlspecialchars(__('Asset type')) . ' | ';
+ echo '' . htmlspecialchars(__('Name')) . ' | ';
+ echo '' . htmlspecialchars(__('Actions', 'urbackup')) . ' | ';
+ echo '
';
+ echo '';
+
+ foreach ($missingAssets as $asset) {
+ $itemtypeLabel = class_exists($asset['itemtype']) ? $asset['itemtype']::getTypeName(1) : $asset['itemtype'];
+ echo '';
+ echo '| ' . htmlspecialchars($itemtypeLabel) . ' | ';
+ echo '' . htmlspecialchars($asset['name']) . ' | ';
+ echo '';
+ echo ' | ';
+ echo '
';
+ }
+
+ echo '';
+ echo '
';
+ }
}
\ No newline at end of file