From 87f0d48d08e204b5995046a0e5d9240cec5911c3 Mon Sep 17 00:00:00 2001 From: tremo Date: Tue, 4 Aug 2026 14:25:03 +0200 Subject: [PATCH 1/2] Fix PDF export of tabs renamed in GLPI 11 --- inc/common.class.php | 15 ++++- inc/computer.class.php | 12 +--- inc/computer_item.class.php | 62 +++++++++++-------- ...irus.class.php => itemantivirus.class.php} | 13 ++-- ...class.php => itemvirtualmachine.class.php} | 44 ++++++------- 5 files changed, 79 insertions(+), 67 deletions(-) rename inc/{computerantivirus.class.php => itemantivirus.class.php} (90%) rename inc/{computervirtualmachine.class.php => itemvirtualmachine.class.php} (74%) diff --git a/inc/common.class.php b/inc/common.class.php index a883614..49509e9 100644 --- a/inc/common.class.php +++ b/inc/common.class.php @@ -30,6 +30,8 @@ * -------------------------------------------------------------------------- */ +use Glpi\Asset\Asset_PeripheralAsset; + abstract class PluginPdfCommon extends CommonGLPI { protected $obj = null; @@ -180,7 +182,8 @@ final public static function displayCommonTabForPDF(PluginPdfSimplePDF $pdf, Com } break; - case 'Ticket$1': + case 'Item_Ticket$1': // tab added on assets + case 'Ticket$1': // tab added on User, Group and SLA if (Ticket::canView()) { PluginPdfItem_Ticket::pdfForItem($pdf, $item); } @@ -230,10 +233,18 @@ final public static function displayCommonTabForPDF(PluginPdfSimplePDF $pdf, Com PluginPdfItem_Disk::pdfForItem($pdf, $item); break; - case 'Computer_Item$1': + case Asset_PeripheralAsset::class . '$1': PluginPdfComputer_Item::pdfForItem($pdf, $item); break; + case 'ItemAntivirus$1': // registered on Computer and Phone + PluginPdfItemAntivirus::pdfForItem($pdf, $item); + break; + + case 'ItemVirtualMachine$1': + PluginPdfItemVirtualMachine::pdfForItem($pdf, $item); + break; + case 'Item_SoftwareVersion$1': PluginPdfItem_SoftwareVersion::pdfForItem($pdf, $item); break; diff --git a/inc/computer.class.php b/inc/computer.class.php index c8851cf..0b610cf 100644 --- a/inc/computer.class.php +++ b/inc/computer.class.php @@ -30,6 +30,8 @@ * -------------------------------------------------------------------------- */ +use Glpi\Asset\Asset_PeripheralAsset; + class PluginPdfComputer extends PluginPdfCommon { public static $rightname = 'plugin_pdf'; @@ -188,15 +190,7 @@ public static function displayTabContentForPDF(PluginPdfSimplePDF $pdf, CommonGL { if ($item instanceof Computer) { switch ($tab) { - case 'ComputerVirtualMachine$1': - PluginPdfComputerVirtualMachine::pdfForComputer($pdf, $item); - break; - - case 'ComputerAntivirus$1': - PluginPdfComputerAntivirus::pdfForComputer($pdf, $item); - break; - - case 'Computer_Item$1': + case Asset_PeripheralAsset::class . '$1': PluginPdfComputer_Item::pdfForComputer($pdf, $item); break; diff --git a/inc/computer_item.class.php b/inc/computer_item.class.php index 7b1f443..b242e93 100644 --- a/inc/computer_item.class.php +++ b/inc/computer_item.class.php @@ -41,37 +41,33 @@ public function __construct(?CommonGLPI $obj = null) $this->obj = ($obj ?: new Asset_PeripheralAsset()); } - public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $comp) + public static function pdfForComputer(PluginPdfSimplePDF $pdf, CommonDBTM $comp) { /** @var DBmysql $DB */ - global $DB; + /** @var array $CFG_GLPI */ + global $DB, $CFG_GLPI; $dbu = new DbUtils(); $ID = $comp->getField('id'); - $items = ['Printer' => _sn('Printer', 'Printers', 2), - 'Monitor' => _sn('Monitor', 'Monitors', 2), - 'Peripheral' => _sn('Device', 'Devices', 2), - 'Phone' => _sn('Phone', 'Phones', 2)]; - $info = new Infocom(); $pdf->setColumnsSize(100); $pdf->displayTitle('' . __s('Direct connections') . ''); - foreach (array_keys($items) as $type) { + foreach ($CFG_GLPI['directconnect_types'] as $type) { $item = $dbu->getItemForItemtype($type); - if (!$item->canView()) { + if (!$item || !$item->canView()) { continue; } $itemTable = $dbu->getTableForItemType($type); $query = [ 'SELECT' => [ 'glpi_assets_assets_peripheralassets.id AS assoc_id', - 'glpi_assets_assets_peripheralassets.computers_id AS assoc_computers_id', - 'glpi_assets_assets_peripheralassets.itemtype', - 'glpi_assets_assets_peripheralassets.items_id', + 'glpi_assets_assets_peripheralassets.items_id_asset AS assoc_items_id_asset', + 'glpi_assets_assets_peripheralassets.itemtype_peripheral', + 'glpi_assets_assets_peripheralassets.items_id_peripheral', 'glpi_assets_assets_peripheralassets.is_dynamic AS assoc_is_dynamic', ], 'FROM' => 'glpi_assets_assets_peripheralassets', @@ -79,13 +75,14 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $comp) $itemTable => [ 'FKEY' => [ $itemTable => 'id', - 'glpi_assets_assets_peripheralassets' => 'items_id', + 'glpi_assets_assets_peripheralassets' => 'items_id_peripheral', ], ], ], 'WHERE' => [ - 'computers_id' => $ID, - 'itemtype' => $type, + 'itemtype_asset' => $comp->getType(), + 'items_id_asset' => $ID, + 'itemtype_peripheral' => $type, 'glpi_assets_assets_peripheralassets.is_deleted' => 0, ], ]; @@ -98,8 +95,7 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $comp) $resultnum = count($result); if ($resultnum > 0) { foreach ($result as $row) { - $tID = $row['items_id']; - $connID = $row['id']; + $tID = $row['items_id_peripheral']; $item->getFromDB($tID); if (!$info->getFromDBforDevice($type, $tID)) { $info->getEmpty(); @@ -177,6 +173,13 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $comp) case 'Phone': $pdf->displayLine(__s('No phone', 'pdf')); break; + + default: + $pdf->displayLine(sprintf( + __s('%1$s: %2$s'), + $item->getTypeName(1), + __s('No item to display'), + )); } } // No row } // each type @@ -188,18 +191,21 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) /** @var DBmysql $DB */ global $DB; + $dbu = new DbUtils(); + $ID = $item->getField('id'); $type = $item->getType(); $info = new Infocom(); - $comp = new Computer(); $pdf->setColumnsSize(100); $title = '' . __s('Direct connections') . ''; $result = $DB->request( - ['FROM' => 'glpi_assets_assets_peripheralassets'] + ['items_id' => $ID, - 'itemtype' => $type], + ['FROM' => 'glpi_assets_assets_peripheralassets', + 'WHERE' => ['itemtype_peripheral' => $type, + 'items_id_peripheral' => $ID, + 'is_deleted' => 0]], ); $resultnum = count($result); @@ -209,10 +215,12 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) $pdf->displayTitle($title); foreach ($result as $row) { - $tID = $row['computers_id']; - $connID = $row['id']; - $comp->getFromDB($tID); - if (!$info->getFromDBforDevice('Computer', $tID)) { + $tID = $row['items_id_asset']; + $comp = $dbu->getItemForItemtype($row['itemtype_asset']); + if (!$comp || !$comp->getFromDB($tID)) { + continue; + } + if (!$info->getFromDBforDevice($row['itemtype_asset'], $tID)) { $info->getEmpty(); } @@ -251,7 +259,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) sprintf( __s('%1$s: %2$s'), '' . __s('Inventory number') . '', - $item->getField('otherserial'), + $comp->fields['otherserial'], ), ); } @@ -269,13 +277,13 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) } if ($line2 !== '' && $line2 !== '0') { $pdf->displayText( - '' . sprintf(__s('%1$s: %2$s'), __s('Computer') . '', ''), + '' . sprintf(__s('%1$s: %2$s'), $comp->getTypeName(1) . '', ''), $line1 . "\n" . $line2, 2, ); } else { $pdf->displayText( - '' . sprintf(__s('%1$s: %2$s'), __s('Computer') . '', ''), + '' . sprintf(__s('%1$s: %2$s'), $comp->getTypeName(1) . '', ''), $line1, 1, ); diff --git a/inc/computerantivirus.class.php b/inc/itemantivirus.class.php similarity index 90% rename from inc/computerantivirus.class.php rename to inc/itemantivirus.class.php index 2ad61d7..d9821c2 100644 --- a/inc/computerantivirus.class.php +++ b/inc/itemantivirus.class.php @@ -30,7 +30,7 @@ * -------------------------------------------------------------------------- */ -class PluginPdfComputerAntivirus extends PluginPdfCommon +class PluginPdfItemAntivirus extends PluginPdfCommon { public static $rightname = 'plugin_pdf'; @@ -39,15 +39,15 @@ public function __construct(?CommonGLPI $obj = null) $this->obj = ($obj ?: new ItemAntivirus()); } - public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) + public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) { /** @var DBmysql $DB */ global $DB; - $ID = $item->getField('id'); - - $result = $DB->request(['FROM' => 'glpi_itemantiviruses'] + ['computers_id' => $ID, - 'is_deleted' => 0]); + $result = $DB->request(['FROM' => 'glpi_itemantiviruses', + 'WHERE' => ['itemtype' => $item->getType(), + 'items_id' => $item->getID(), + 'is_deleted' => 0]]); $number = count($result); $pdf->setColumnsSize(100); @@ -74,7 +74,6 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) __s('Expiration date'), ); - $antivirus = new ItemAntivirus(); foreach ($result as $data) { $pdf->displayLine( $data['name'], diff --git a/inc/computervirtualmachine.class.php b/inc/itemvirtualmachine.class.php similarity index 74% rename from inc/computervirtualmachine.class.php rename to inc/itemvirtualmachine.class.php index 5affc15..90779ea 100644 --- a/inc/computervirtualmachine.class.php +++ b/inc/itemvirtualmachine.class.php @@ -30,7 +30,7 @@ * -------------------------------------------------------------------------- */ -class PluginPdfComputerVirtualMachine extends PluginPdfCommon +class PluginPdfItemVirtualMachine extends PluginPdfCommon { public static $rightname = 'plugin_pdf'; @@ -39,16 +39,18 @@ public function __construct(?CommonGLPI $obj = null) $this->obj = ($obj ?: new ItemVirtualMachine()); } - public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) + public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item) { $dbu = new DbUtils(); $ID = $item->getField('id'); - // From ComputerVirtualMachine::showForComputer() + // From ItemVirtualMachine::showForAsset() $virtualmachines = $dbu->getAllDataFromTable( 'glpi_itemvirtualmachines', - ['computers_id' => $ID], + ['WHERE' => ['itemtype' => $item->getType(), + 'items_id' => $ID], + 'ORDER' => 'name'], ); $pdf->setColumnsSize(100); $title = '' . __s('List of virtualized environments') . ''; @@ -56,7 +58,7 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) $number = count($virtualmachines); if ($number === 0) { - $pdf->displayTitle('' . __s('No virtualized environment associated with the computer') . ''); + $pdf->displayTitle(sprintf(__s('%1$s: %2$s'), $title, __s('No item to display'))); } else { if ($number > $_SESSION['glpilist_limit']) { $title = sprintf(__s('%1$s: %2$s'), $title, $_SESSION['glpilist_limit'] . ' / ' . $number); @@ -80,10 +82,10 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) foreach ($virtualmachines as $virtualmachine) { $name = ''; - if ($link_computer = ItemVirtualMachine::findVirtualMachine($virtualmachine)) { - $computer = new Computer(); - if ($computer->getFromDB($link_computer)) { - $name = $computer->getName(); + if ($link_item = ItemVirtualMachine::findVirtualMachine($virtualmachine)) { + $linked = $dbu->getItemForItemtype($virtualmachine['itemtype']); + if ($linked && $linked->getFromDB($link_item)) { + $name = $linked->getName(); } } $pdf->displayLine( @@ -108,10 +110,11 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) } } - // From ComputerVirtualMachine::showForVirtualMachine() - if ($item->fields['uuid']) { + // From ItemVirtualMachine::showForVirtualMachine() + // The exported item may itself be a guest: look for the host(s) declaring a virtual machine having its UUID. + if (!empty($item->fields['uuid'])) { $hosts = $dbu->getAllDataFromTable( - $item::getTable(), + 'glpi_itemvirtualmachines', ['RAW' => ['LOWER(uuid)' => ItemVirtualMachine::getUUIDRestrictCriteria($item->fields['uuid']), @@ -121,21 +124,18 @@ public static function pdfForComputer(PluginPdfSimplePDF $pdf, Computer $item) if (count($hosts)) { $pdf->setColumnsSize(100); - $pdf->displayTitle('' . __s('List of virtualized environments') . ''); + $pdf->displayTitle('' . __s('List of hosts') . ''); $pdf->setColumnsSize(26, 37, 37); - $pdf->displayTitle(__s('Name'), __s('Operating system'), __s('Entity')); + $pdf->displayTitle(__s('Name'), __s('Serial number'), __s('Entity')); - $computer = new Computer(); foreach ($hosts as $host) { - if ($computer->getFromDB($host['id'])) { + $host_item = $dbu->getItemForItemtype($host['itemtype']); + if ($host_item && $host_item->getFromDB($host['items_id'])) { $pdf->displayLine( - $computer->getName(), - Toolbox::stripTags(Dropdown::getDropdownName( - 'glpi_operatingsystems', - $computer->getField('operatingsystems_id'), - )), - Dropdown::getDropdownName('glpi_entities', $computer->getEntityID()), + $host_item->getName(), + Toolbox::stripTags((string) $host_item->getField('serial')), + Dropdown::getDropdownName('glpi_entities', $host_item->getEntityID()), ); } } From 7ccacd2a37876aa24371ae64c1e17d24dc1f0182 Mon Sep 17 00:00:00 2001 From: tremo Date: Tue, 4 Aug 2026 15:09:32 +0200 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc7c52..1bf37c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Fixed + +- Fix PDF export of tabs renamed in GLPI 11 + ## [4.1.4] - 2026-07-30 ### Fixed