diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7f42bf7..1a14412 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fix image (field : description) in to pdf
- Fix massive action PDF export redirecting to item list instead of generating the PDF
+- Fix PDF export for assignable asset groups by properly handling multiple groups
## [4.1.2] - 2026-01-08
diff --git a/inc/common.class.php b/inc/common.class.php
index a883614..b40856f 100644
--- a/inc/common.class.php
+++ b/inc/common.class.php
@@ -30,6 +30,8 @@
* --------------------------------------------------------------------------
*/
+use Glpi\Features\AssignableItemInterface;
+
abstract class PluginPdfCommon extends CommonGLPI
{
protected $obj = null;
@@ -37,6 +39,34 @@ abstract class PluginPdfCommon extends CommonGLPI
public static $rightname = 'plugin_pdf';
+ protected static function getGroupName(CommonDBTM $item, int $group_type = Group_Item::GROUP_TYPE_NORMAL): string
+ {
+ $field = $group_type === Group_Item::GROUP_TYPE_TECH ? 'groups_id_tech' : 'groups_id';
+
+ if ($item instanceof AssignableItemInterface) {
+ // Many-to-many relation, stored in the glpi_groups_items pivot table
+ global $DB;
+ $it = $DB->request([
+ 'SELECT' => 'groups_id',
+ 'FROM' => Group_Item::getTable(),
+ 'WHERE' => [
+ 'itemtype' => $item::class,
+ 'items_id' => $item->getID(),
+ 'type' => $group_type,
+ ],
+ ]);
+ $group_ids = array_column(iterator_to_array($it), 'groups_id');
+ } else {
+ // One-to-one relation, direct column on the item (e.g. glpi_itilcategories)
+ $group_ids = (array) ($item->fields[$field] ?? 0);
+ }
+
+ return implode(', ', array_filter(array_map(
+ static fn($group_id) => Toolbox::stripTags(Dropdown::getDropdownName('glpi_groups', $group_id)),
+ $group_ids,
+ )));
+ }
+
/**
* Constructor, should intialize $this->obj property
**/
@@ -59,6 +89,7 @@ public function addStandardTab($itemtype, array &$ong, array $options)
$withtemplate = $options['withtemplate'];
}
+ // @phpstan-ignore-next-line function.impossibleType (itemtype is not always a class-string at runtime, despite CommonGLPI's phpdoc)
if (!is_numeric($itemtype) && ($obj = $dbu->getItemForItemtype($itemtype)) && (method_exists($itemtype, 'displayTabContentForPDF'))) {
$titles = $obj->getTabNameForItem($this->obj, $withtemplate);
if (!is_array($titles)) {
@@ -509,10 +540,7 @@ public static function mainLine(PluginPdfSimplePDF $pdf, $item, $field)
'' . sprintf(
__s('%1$s: %2$s'),
__s('Group in charge of the hardware') . '',
- Dropdown::getDropdownName(
- 'glpi_groups',
- $item->fields['groups_id_tech'],
- ),
+ self::getGroupName($item, Group_Item::GROUP_TYPE_TECH),
),
'' . sprintf(
__s('%1$s: %2$s'),
diff --git a/inc/computer.class.php b/inc/computer.class.php
index c8851cf..fab9647 100644
--- a/inc/computer.class.php
+++ b/inc/computer.class.php
@@ -89,12 +89,21 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Computer $computer)
'' . sprintf(
__('%1$s: %2$s'),
__('Group') . '',
- Dropdown::getDropdownName(
- 'glpi_groups',
- $computer->fields['groups_id'],
- ),
+ self::getGroupName($computer),
+ ),
+ '' . sprintf(
+ __('%1$s: %2$s'),
+ __('Group in charge of the hardware') . '',
+ self::getGroupName($computer, Group_Item::GROUP_TYPE_TECH),
+ ),
+ );
+
+ $pdf->displayLine(
+ '' . sprintf(
+ __('%1$s: %2$s'),
+ __('UUID') . '',
+ $computer->fields['uuid'],
),
- '' . sprintf(__('%1$s: %2$s'), __('UUID') . '', $computer->fields['uuid']),
);
$pdf->displayLine(
diff --git a/inc/monitor.class.php b/inc/monitor.class.php
index 5d7ccc7..5a8516d 100644
--- a/inc/monitor.class.php
+++ b/inc/monitor.class.php
@@ -61,11 +61,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Monitor $item)
PluginPdfCommon::mainLine($pdf, $item, 'user-management');
$pdf->displayLine(
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $item->fields['groups_id']),
- ),
+ '' . sprintf(__s('%1$s: %2$s'), __s('Group') . '', self::getGroupName($item)),
'' . sprintf(
__s('%1$s: %2$s'),
__s('Size') . '',
diff --git a/inc/networkequipment.class.php b/inc/networkequipment.class.php
index cbd1155..993d199 100644
--- a/inc/networkequipment.class.php
+++ b/inc/networkequipment.class.php
@@ -83,11 +83,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, NetworkEquipment $item)
);
$pdf->displayLine(
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $item->fields['groups_id']),
- ),
+ '' . sprintf(__s('%1$s: %2$s'), __s('Group') . '', self::getGroupName($item)),
'' . __s('The MAC address and the IP of the equipment are included in an aggregated network port'),
'' . sprintf(
__s('%1$s: %2$s'),
diff --git a/inc/peripheral.class.php b/inc/peripheral.class.php
index 9f38312..e5ab9f2 100644
--- a/inc/peripheral.class.php
+++ b/inc/peripheral.class.php
@@ -63,11 +63,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Peripheral $item)
PluginPdfCommon::mainLine($pdf, $item, 'user-management');
$pdf->displayLine(
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $item->fields['groups_id']),
- ),
+ '' . sprintf(__s('%1$s: %2$s'), __s('Group') . '', self::getGroupName($item)),
'' . sprintf(__s('%1$s: %2$s'), __s('Brand') . '', $item->fields['brand']),
);
diff --git a/inc/phone.class.php b/inc/phone.class.php
index e35cf92..187fe79 100644
--- a/inc/phone.class.php
+++ b/inc/phone.class.php
@@ -64,16 +64,8 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Phone $item)
$pdf->displayLine(
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $item->fields['groups_id']),
- ),
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('UUID') . '',
- $item->fields['uuid'],
- ),
+ '' . sprintf(__s('%1$s: %2$s'), __s('Group') . '', self::getGroupName($item)),
+ '' . sprintf(__s('%1$s: %2$s'), __s('UUID') . '', $item->fields['uuid']),
);
$pdf->displayLine(
diff --git a/inc/printer.class.php b/inc/printer.class.php
index d493fc0..b3ab619 100644
--- a/inc/printer.class.php
+++ b/inc/printer.class.php
@@ -96,16 +96,8 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Printer $printer)
);
$pdf->displayLine(
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $printer->fields['groups_id']),
- ),
- '' . sprintf(
- __s('%1$s: %2$s'),
- __s('UUID') . '',
- $printer->fields['uuid'],
- ),
+ '' . sprintf(__s('%1$s: %2$s'), __s('Group') . '', self::getGroupName($printer)),
+ '' . sprintf(__s('%1$s: %2$s'), __s('UUID') . '', $printer->fields['uuid']),
);
diff --git a/inc/software.class.php b/inc/software.class.php
index 21a3526..c48fee3 100644
--- a/inc/software.class.php
+++ b/inc/software.class.php
@@ -93,10 +93,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Software $software)
'' . sprintf(
__s('%1$s: %2$s'),
__s('Group in charge of the hardware') . '',
- Dropdown::getDropdownName(
- 'glpi_groups',
- $software->fields['groups_id_tech'],
- ),
+ self::getGroupName($software, Group_Item::GROUP_TYPE_TECH),
),
'' . sprintf(
__s('%1$s: %2$s'),
@@ -109,7 +106,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Software $software)
'' . sprintf(
__s('%1$s: %2$s'),
__s('Group') . '',
- Dropdown::getDropdownName('glpi_groups', $software->fields['groups_id']),
+ self::getGroupName($software),
),
);