From 6db8290ab70db954ad33fafd2be2c9aefb22ffb1 Mon Sep 17 00:00:00 2001
From: Rom1-B <8530352+Rom1-B@users.noreply.github.com>
Date: Tue, 18 Aug 2026 15:09:11 +0200
Subject: [PATCH 01/11] feature/glpi-12.0
---
.github/workflows/continuous-integration.yml | 2 +-
CHANGELOG.md | 4 +++
inc/appliance.class.php | 2 +-
inc/cartridge.class.php | 2 +-
inc/cartridgeitem.class.php | 2 +-
inc/change.class.php | 2 +-
inc/change_item.class.php | 6 ++--
inc/change_problem.class.php | 10 +++---
inc/change_ticket.class.php | 10 +++---
inc/changetask.class.php | 2 +-
inc/changevalidation.class.php | 2 +-
inc/common.class.php | 2 +-
inc/commonitilcost.class.php | 2 +-
inc/computer.class.php | 2 +-
inc/computer_item.class.php | 2 +-
inc/computer_softwarelicense.class.php | 2 +-
inc/computer_softwareversion.class.php | 2 +-
inc/config.class.php | 2 +-
inc/consumableitem.class.php | 4 +--
inc/contract.class.php | 2 +-
inc/contract_item.class.php | 2 +-
inc/document.class.php | 2 +-
inc/domain_item.class.php | 2 +-
inc/group.class.php | 2 +-
inc/group_user.class.php | 2 +-
inc/infocom.class.php | 2 +-
inc/item_device.class.php | 2 +-
inc/item_disk.class.php | 2 +-
inc/item_knowbaseitem.class.php | 2 +-
inc/item_operatingsystem.class.php | 2 +-
inc/item_problem.class.php | 6 ++--
inc/item_softwarelicense.class.php | 2 +-
inc/item_softwareversion.class.php | 2 +-
inc/item_ticket.class.php | 6 ++--
inc/itemantivirus.class.php | 2 +-
inc/itemvirtualmachine.class.php | 2 +-
inc/itilfollowup.class.php | 2 +-
inc/itilsolution.class.php | 2 +-
inc/knowbaseitem.class.php | 2 +-
inc/link.class.php | 2 +-
inc/log.class.php | 2 +-
inc/monitor.class.php | 2 +-
inc/networkequipment.class.php | 2 +-
inc/networkport.class.php | 2 +-
inc/peripheral.class.php | 2 +-
inc/phone.class.php | 2 +-
inc/preference.class.php | 2 +-
inc/printer.class.php | 2 +-
inc/problem.class.php | 2 +-
inc/problem_ticket.class.php | 10 +++---
inc/problemtask.class.php | 2 +-
inc/profile.class.php | 6 ++--
inc/reservation.class.php | 2 +-
inc/software.class.php | 2 +-
inc/softwarelicense.class.php | 2 +-
inc/softwareversion.class.php | 2 +-
inc/ticket.class.php | 2 +-
inc/ticket_contract.class.php | 2 +-
inc/ticketsatisfaction.class.php | 2 +-
inc/tickettask.class.php | 2 +-
inc/ticketvalidation.class.php | 2 +-
inc/user.class.php | 2 +-
setup.php | 4 +--
templates/preference_form.html.twig | 33 --------------------
64 files changed, 88 insertions(+), 117 deletions(-)
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 62d4e17d..b5c91c38 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -53,7 +53,7 @@ jobs:
name: "Generate CI matrix"
uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1"
with:
- glpi-version: "11.0.x"
+ glpi-version: "12.0.x"
ci:
name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}"
needs: "generate-ci-matrix"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e14fcbce..7c49bcd9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [4.1.5] - 2026-09-01
+### Added
+
+- GLPI 12 compatibility
+
### Fixed
- Fix PDF Generation involving a Network port with multiple IPs
diff --git a/inc/appliance.class.php b/inc/appliance.class.php
index 62852ef8..a4f76e27 100644
--- a/inc/appliance.class.php
+++ b/inc/appliance.class.php
@@ -32,7 +32,7 @@
class PluginPdfAppliance extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
/**
* @param $obj (defult NULL)
diff --git a/inc/cartridge.class.php b/inc/cartridge.class.php
index efda6d04..9daa8cce 100644
--- a/inc/cartridge.class.php
+++ b/inc/cartridge.class.php
@@ -32,7 +32,7 @@
class PluginPdfCartridge extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
/**
* @param $obj (defult NULL)
diff --git a/inc/cartridgeitem.class.php b/inc/cartridgeitem.class.php
index 63a09db5..cfa54ded 100644
--- a/inc/cartridgeitem.class.php
+++ b/inc/cartridgeitem.class.php
@@ -32,7 +32,7 @@
class PluginPdfCartridgeItem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/change.class.php b/inc/change.class.php
index 1a6d8ac4..43f9e64e 100644
--- a/inc/change.class.php
+++ b/inc/change.class.php
@@ -32,7 +32,7 @@
class PluginPdfChange extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/change_item.class.php b/inc/change_item.class.php
index dca4a695..36140f55 100644
--- a/inc/change_item.class.php
+++ b/inc/change_item.class.php
@@ -32,7 +32,7 @@
class PluginPdfChange_Item extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -384,7 +384,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -425,7 +425,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/change_problem.class.php b/inc/change_problem.class.php
index 16eca1b7..6fe62f8f 100644
--- a/inc/change_problem.class.php
+++ b/inc/change_problem.class.php
@@ -32,7 +32,7 @@
class PluginPdfChange_Problem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -225,7 +225,7 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -266,7 +266,7 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', ('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
@@ -452,7 +452,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -493,7 +493,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/change_ticket.class.php b/inc/change_ticket.class.php
index 97127939..4b927a2e 100644
--- a/inc/change_ticket.class.php
+++ b/inc/change_ticket.class.php
@@ -32,7 +32,7 @@
class PluginPdfChange_Ticket extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -226,7 +226,7 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -267,7 +267,7 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
@@ -483,7 +483,7 @@ public static function pdfForTicket(PluginPdfSimplePDF $pdf, Ticket $ticket)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -524,7 +524,7 @@ public static function pdfForTicket(PluginPdfSimplePDF $pdf, Ticket $ticket)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/changetask.class.php b/inc/changetask.class.php
index c438de71..d782a3be 100644
--- a/inc/changetask.class.php
+++ b/inc/changetask.class.php
@@ -32,7 +32,7 @@
class PluginPdfChangeTask extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/changevalidation.class.php b/inc/changevalidation.class.php
index 2a8e7132..486981b4 100644
--- a/inc/changevalidation.class.php
+++ b/inc/changevalidation.class.php
@@ -32,7 +32,7 @@
class PluginPdfChangeValidation extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/common.class.php b/inc/common.class.php
index 49509e94..98acf9d7 100644
--- a/inc/common.class.php
+++ b/inc/common.class.php
@@ -37,7 +37,7 @@ abstract class PluginPdfCommon extends CommonGLPI
protected $obj = null;
protected $pdf = null;
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
/**
* Constructor, should intialize $this->obj property
diff --git a/inc/commonitilcost.class.php b/inc/commonitilcost.class.php
index 8532c2bc..776e938e 100644
--- a/inc/commonitilcost.class.php
+++ b/inc/commonitilcost.class.php
@@ -32,7 +32,7 @@
class PluginPdfCommonItilCost extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/computer.class.php b/inc/computer.class.php
index 0b610cf3..c0949d17 100644
--- a/inc/computer.class.php
+++ b/inc/computer.class.php
@@ -34,7 +34,7 @@
class PluginPdfComputer extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/computer_item.class.php b/inc/computer_item.class.php
index b242e933..f04d731d 100644
--- a/inc/computer_item.class.php
+++ b/inc/computer_item.class.php
@@ -34,7 +34,7 @@
class PluginPdfComputer_Item extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/computer_softwarelicense.class.php b/inc/computer_softwarelicense.class.php
index 67ac3f26..30e1f7dc 100644
--- a/inc/computer_softwarelicense.class.php
+++ b/inc/computer_softwarelicense.class.php
@@ -63,7 +63,7 @@
*/
class PluginPdfComputer_SoftwareLicense extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/computer_softwareversion.class.php b/inc/computer_softwareversion.class.php
index 306ba5a3..5c22df57 100644
--- a/inc/computer_softwareversion.class.php
+++ b/inc/computer_softwareversion.class.php
@@ -63,7 +63,7 @@
*/
class PluginPdfComputer_SoftwareVersion extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/config.class.php b/inc/config.class.php
index 7dc583b5..896a2d99 100644
--- a/inc/config.class.php
+++ b/inc/config.class.php
@@ -65,7 +65,7 @@
class PluginPdfConfig extends CommonDBTM
{
private static $_instance = null;
- public static $rightname = 'config';
+ public static string $rightname = 'config';
public static function canCreate(): bool
{
diff --git a/inc/consumableitem.class.php b/inc/consumableitem.class.php
index 991a641f..737022bb 100644
--- a/inc/consumableitem.class.php
+++ b/inc/consumableitem.class.php
@@ -32,7 +32,7 @@
class PluginPdfConsumableItem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -165,7 +165,7 @@ public static function pdfForConsumableItem(PluginPdfSimplePDF $pdf, ConsumableI
'ORDER' => $order],
);
- if (!$number) {
+ if ($number === 0) {
$pdf->setColumnsSize(100);
$pdf->displayTitle(__s('No consumable'));
} else {
diff --git a/inc/contract.class.php b/inc/contract.class.php
index c44664a0..c127dc1d 100644
--- a/inc/contract.class.php
+++ b/inc/contract.class.php
@@ -32,7 +32,7 @@
class PluginPdfContract extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/contract_item.class.php b/inc/contract_item.class.php
index ed33e589..bbd41c25 100644
--- a/inc/contract_item.class.php
+++ b/inc/contract_item.class.php
@@ -32,7 +32,7 @@
class PluginPdfContract_Item extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/document.class.php b/inc/document.class.php
index 418cd128..ad67286c 100644
--- a/inc/document.class.php
+++ b/inc/document.class.php
@@ -32,7 +32,7 @@
class PluginPdfDocument extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/domain_item.class.php b/inc/domain_item.class.php
index 22e54562..cfc106b8 100644
--- a/inc/domain_item.class.php
+++ b/inc/domain_item.class.php
@@ -32,7 +32,7 @@
class PluginPdfDomain_Item extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/group.class.php b/inc/group.class.php
index 31eea5d1..07ed6a4f 100644
--- a/inc/group.class.php
+++ b/inc/group.class.php
@@ -32,7 +32,7 @@
class PluginPdfGroup extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/group_user.class.php b/inc/group_user.class.php
index a1d02b18..ed856f6d 100644
--- a/inc/group_user.class.php
+++ b/inc/group_user.class.php
@@ -32,7 +32,7 @@
class PluginPdfGroup_User extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/infocom.class.php b/inc/infocom.class.php
index 37b45a45..d19a20ec 100644
--- a/inc/infocom.class.php
+++ b/inc/infocom.class.php
@@ -32,7 +32,7 @@
class PluginPdfInfocom extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_device.class.php b/inc/item_device.class.php
index 27c715ff..37968590 100644
--- a/inc/item_device.class.php
+++ b/inc/item_device.class.php
@@ -33,7 +33,7 @@
class PluginPdfItem_Device extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_disk.class.php b/inc/item_disk.class.php
index 7c0f1651..fe11cbad 100644
--- a/inc/item_disk.class.php
+++ b/inc/item_disk.class.php
@@ -32,7 +32,7 @@
class PluginPdfItem_Disk extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_knowbaseitem.class.php b/inc/item_knowbaseitem.class.php
index 2096bc91..533238a1 100644
--- a/inc/item_knowbaseitem.class.php
+++ b/inc/item_knowbaseitem.class.php
@@ -32,7 +32,7 @@
class PluginPdfItem_Knowbaseitem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_operatingsystem.class.php b/inc/item_operatingsystem.class.php
index 50686fe7..15262ee7 100644
--- a/inc/item_operatingsystem.class.php
+++ b/inc/item_operatingsystem.class.php
@@ -32,7 +32,7 @@
class PluginPdfItem_OperatingSystem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_problem.class.php b/inc/item_problem.class.php
index 0ceb1fba..32a83683 100644
--- a/inc/item_problem.class.php
+++ b/inc/item_problem.class.php
@@ -63,7 +63,7 @@
*/
class PluginPdfItem_Problem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -472,7 +472,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -513,7 +513,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/item_softwarelicense.class.php b/inc/item_softwarelicense.class.php
index 35aa2cf7..9fff1670 100644
--- a/inc/item_softwarelicense.class.php
+++ b/inc/item_softwarelicense.class.php
@@ -63,7 +63,7 @@
*/
class PluginPdfItem_SoftwareLicense extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_softwareversion.class.php b/inc/item_softwareversion.class.php
index a67b47c1..b973d6ae 100644
--- a/inc/item_softwareversion.class.php
+++ b/inc/item_softwareversion.class.php
@@ -64,7 +64,7 @@
*/
class PluginPdfItem_SoftwareVersion extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/item_ticket.class.php b/inc/item_ticket.class.php
index 0c0a2ca8..e42b7128 100644
--- a/inc/item_ticket.class.php
+++ b/inc/item_ticket.class.php
@@ -63,7 +63,7 @@
*/
class PluginPdfItem_Ticket extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -516,7 +516,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -557,7 +557,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/itemantivirus.class.php b/inc/itemantivirus.class.php
index d9821c26..1d143ff5 100644
--- a/inc/itemantivirus.class.php
+++ b/inc/itemantivirus.class.php
@@ -32,7 +32,7 @@
class PluginPdfItemAntivirus extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/itemvirtualmachine.class.php b/inc/itemvirtualmachine.class.php
index 90779ea8..bc4fa09d 100644
--- a/inc/itemvirtualmachine.class.php
+++ b/inc/itemvirtualmachine.class.php
@@ -32,7 +32,7 @@
class PluginPdfItemVirtualMachine extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/itilfollowup.class.php b/inc/itilfollowup.class.php
index 1ef03b1d..55895a56 100644
--- a/inc/itilfollowup.class.php
+++ b/inc/itilfollowup.class.php
@@ -32,7 +32,7 @@
class PluginPdfItilFollowup extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/itilsolution.class.php b/inc/itilsolution.class.php
index 94302fe2..9526f1ae 100644
--- a/inc/itilsolution.class.php
+++ b/inc/itilsolution.class.php
@@ -32,7 +32,7 @@
class PluginPdfITILSolution extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/knowbaseitem.class.php b/inc/knowbaseitem.class.php
index e01d23da..677065bc 100644
--- a/inc/knowbaseitem.class.php
+++ b/inc/knowbaseitem.class.php
@@ -32,7 +32,7 @@
class PluginPdfKnowbaseItem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/link.class.php b/inc/link.class.php
index b4e040db..22b5df38 100644
--- a/inc/link.class.php
+++ b/inc/link.class.php
@@ -32,7 +32,7 @@
class PluginPdfLink extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/log.class.php b/inc/log.class.php
index feb190c1..382da092 100644
--- a/inc/log.class.php
+++ b/inc/log.class.php
@@ -32,7 +32,7 @@
class PluginPdfLog extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/monitor.class.php b/inc/monitor.class.php
index 5d7ccc7e..a2aca15e 100644
--- a/inc/monitor.class.php
+++ b/inc/monitor.class.php
@@ -32,7 +32,7 @@
class PluginPdfMonitor extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/networkequipment.class.php b/inc/networkequipment.class.php
index cbd11557..afba623a 100644
--- a/inc/networkequipment.class.php
+++ b/inc/networkequipment.class.php
@@ -32,7 +32,7 @@
class PluginPdfNetworkEquipment extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/networkport.class.php b/inc/networkport.class.php
index bfb2390f..81cce055 100644
--- a/inc/networkport.class.php
+++ b/inc/networkport.class.php
@@ -34,7 +34,7 @@
class PluginPdfNetworkPort extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/peripheral.class.php b/inc/peripheral.class.php
index 9f383122..06d9fd70 100644
--- a/inc/peripheral.class.php
+++ b/inc/peripheral.class.php
@@ -32,7 +32,7 @@
class PluginPdfPeripheral extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/phone.class.php b/inc/phone.class.php
index e35cf925..e69766d5 100644
--- a/inc/phone.class.php
+++ b/inc/phone.class.php
@@ -32,7 +32,7 @@
class PluginPdfPhone extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/preference.class.php b/inc/preference.class.php
index 15a8dc78..0208cae6 100644
--- a/inc/preference.class.php
+++ b/inc/preference.class.php
@@ -34,7 +34,7 @@
class PluginPdfPreference extends CommonDBTM
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public static function getTypeName($nb = 0)
{
diff --git a/inc/printer.class.php b/inc/printer.class.php
index d493fc01..35d3b242 100644
--- a/inc/printer.class.php
+++ b/inc/printer.class.php
@@ -32,7 +32,7 @@
class PluginPdfPrinter extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/problem.class.php b/inc/problem.class.php
index 24849501..b492a5d8 100644
--- a/inc/problem.class.php
+++ b/inc/problem.class.php
@@ -32,7 +32,7 @@
class PluginPdfProblem extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/problem_ticket.class.php b/inc/problem_ticket.class.php
index e1629ece..96c118c8 100644
--- a/inc/problem_ticket.class.php
+++ b/inc/problem_ticket.class.php
@@ -32,7 +32,7 @@
class PluginPdfProblem_Ticket extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
@@ -223,7 +223,7 @@ public static function pdfForTicket(PluginPdfSimplePDF $pdf, Ticket $ticket)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -264,7 +264,7 @@ public static function pdfForTicket(PluginPdfSimplePDF $pdf, Ticket $ticket)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', ('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
@@ -448,7 +448,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s'), __s('Requester') . ' ', '');
$pdf->displayText($texte, $col, 1);
}
@@ -489,7 +489,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
$first = false;
}
}
- if ($col) {
+ if ($col !== '' && $col !== '0') {
$texte = '' . sprintf(__s('%1$s: %2$s') . ' ', __s('Assigned to'), '');
$pdf->displayText($texte, $col, 1);
}
diff --git a/inc/problemtask.class.php b/inc/problemtask.class.php
index f89d5065..c49d4d42 100755
--- a/inc/problemtask.class.php
+++ b/inc/problemtask.class.php
@@ -32,7 +32,7 @@
class PluginPdfProblemTask extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/profile.class.php b/inc/profile.class.php
index 19350b29..aea669e5 100644
--- a/inc/profile.class.php
+++ b/inc/profile.class.php
@@ -32,7 +32,7 @@
class PluginPdfProfile extends Profile
{
- public static $rightname = 'profile';
+ public static string $rightname = 'profile';
public static function getTypeName($nb = 0)
{
@@ -127,11 +127,11 @@ public static function addDefaultProfileInfos($profiles_id, $rights, $drop_exist
'name' => $right]);
}
- if (!$dbu->countElementsInTable(
+ if ($dbu->countElementsInTable(
'glpi_profilerights',
['profiles_id' => $profiles_id,
'name' => $right],
- )) {
+ ) === 0) {
$myright['profiles_id'] = $profiles_id;
$myright['name'] = $right;
$myright['rights'] = $value;
diff --git a/inc/reservation.class.php b/inc/reservation.class.php
index 69c4545a..c72c521f 100644
--- a/inc/reservation.class.php
+++ b/inc/reservation.class.php
@@ -32,7 +32,7 @@
class PluginPdfReservation extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/software.class.php b/inc/software.class.php
index 21a3526e..5a58167a 100644
--- a/inc/software.class.php
+++ b/inc/software.class.php
@@ -32,7 +32,7 @@
class PluginPdfSoftware extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/softwarelicense.class.php b/inc/softwarelicense.class.php
index 3f712645..53f2d866 100644
--- a/inc/softwarelicense.class.php
+++ b/inc/softwarelicense.class.php
@@ -32,7 +32,7 @@
class PluginPdfSoftwareLicense extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/softwareversion.class.php b/inc/softwareversion.class.php
index 3c1fb1b2..b404a9fb 100644
--- a/inc/softwareversion.class.php
+++ b/inc/softwareversion.class.php
@@ -32,7 +32,7 @@
class PluginPdfSoftwareVersion extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/ticket.class.php b/inc/ticket.class.php
index 78677a76..13646308 100644
--- a/inc/ticket.class.php
+++ b/inc/ticket.class.php
@@ -32,7 +32,7 @@
class PluginPdfTicket extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/ticket_contract.class.php b/inc/ticket_contract.class.php
index ee33a239..ff3630e2 100644
--- a/inc/ticket_contract.class.php
+++ b/inc/ticket_contract.class.php
@@ -32,7 +32,7 @@
class PluginPdfTicket_Contract extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/ticketsatisfaction.class.php b/inc/ticketsatisfaction.class.php
index 09fbecd6..9f056c2a 100644
--- a/inc/ticketsatisfaction.class.php
+++ b/inc/ticketsatisfaction.class.php
@@ -32,7 +32,7 @@
class PluginPdfTicketSatisfaction extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/tickettask.class.php b/inc/tickettask.class.php
index 55e5d902..596af6fa 100644
--- a/inc/tickettask.class.php
+++ b/inc/tickettask.class.php
@@ -32,7 +32,7 @@
class PluginPdfTicketTask extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/ticketvalidation.class.php b/inc/ticketvalidation.class.php
index 848934c2..9fabf820 100644
--- a/inc/ticketvalidation.class.php
+++ b/inc/ticketvalidation.class.php
@@ -32,7 +32,7 @@
class PluginPdfTicketValidation extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/inc/user.class.php b/inc/user.class.php
index 838d5c81..61e05357 100644
--- a/inc/user.class.php
+++ b/inc/user.class.php
@@ -32,7 +32,7 @@
class PluginPdfUser extends PluginPdfCommon
{
- public static $rightname = 'plugin_pdf';
+ public static string $rightname = 'plugin_pdf';
public function __construct(?CommonGLPI $obj = null)
{
diff --git a/setup.php b/setup.php
index 100b41cc..9a85facf 100644
--- a/setup.php
+++ b/setup.php
@@ -36,8 +36,8 @@
define('PLUGIN_PDF_VERSION', '4.1.5');
-define('PLUGIN_PDF_MIN_GLPI', '11.0.0');
-define('PLUGIN_PDF_MAX_GLPI', '11.0.99');
+define('PLUGIN_PDF_MIN_GLPI', '12.0.0');
+define('PLUGIN_PDF_MAX_GLPI', '12.0.99');
function plugin_init_pdf()
{
diff --git a/templates/preference_form.html.twig b/templates/preference_form.html.twig
index ffbfbd41..29c493ca 100644
--- a/templates/preference_form.html.twig
+++ b/templates/preference_form.html.twig
@@ -146,7 +146,6 @@
-
{% if item_id %}
@@ -206,37 +205,5 @@
});
updateSelectionCount(formId);
-
- function refreshCsrfToken(formId) {
- fetch(window.location.href, { credentials: 'same-origin' })
- .then(r => r.text())
- .then(html => {
- try {
- const newTokenInput = new DOMParser()
- .parseFromString(html, 'text/html')
- .querySelector('input[name="_glpi_csrf_token"]');
- if (!newTokenInput) return;
-
- const currentTokenInput = document.querySelector(`#${formId} input[name="_glpi_csrf_token"]`);
- if (currentTokenInput) {
- currentTokenInput.value = newTokenInput.value;
- }
- } catch (e) {
- // Ignore errors silently
- }
- })
- .catch(() => {
- // Ignore errors silently
- });
- }
-
- // Schedule a CSRF token refresh after form submission
- const form = document.getElementById(formId);
- if (form) {
- form.addEventListener('submit', () => {
- // Delay to allow server-side AJAX handlers to complete; full navigation will reload everything
- setTimeout(() => refreshCsrfToken(formId), 800);
- });
- }
});
From 2119be63c3a4d632425bc0146dc3133b50341b8f Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Thu, 3 Sep 2026 10:06:56 +0200
Subject: [PATCH 02/11] chore: remove deprecated Rector rule
---
rector.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/rector.php b/rector.php
index 65a1f6ed..35d41f46 100644
--- a/rector.php
+++ b/rector.php
@@ -67,7 +67,6 @@
CodeQuality\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector::class,
CodeQuality\Foreach_\ForeachToInArrayRector::class,
CodeQuality\Foreach_\SimplifyForeachToCoalescingRector::class,
- CodeQuality\Foreach_\UnusedForeachValueToArrayKeysRector::class,
CodeQuality\FuncCall\ChangeArrayPushToArrayAssignRector::class,
CodeQuality\FuncCall\CompactToVariablesRector::class,
CodeQuality\FuncCall\InlineIsAInstanceOfRector::class,
From 5465b6cbc958f204b6034c28a1cdb9e089f8d056 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Thu, 3 Sep 2026 10:07:06 +0200
Subject: [PATCH 03/11] chore: rector lint
---
inc/cartridge.class.php | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/inc/cartridge.class.php b/inc/cartridge.class.php
index 9daa8cce..b69a6e12 100644
--- a/inc/cartridge.class.php
+++ b/inc/cartridge.class.php
@@ -366,10 +366,7 @@ public static function pdfForCartridgeItem(PluginPdfSimplePDF $pdf, CartridgeIte
- mktime(0, 0, 0, (int) $tmp_dbeg[1], (int) $tmp_dbeg[2], (int) $tmp_dbeg[0]);
$use_time += $use_time_tmp;
- // Get initial counter page
- if (!isset($pages[$printer])) {
- $pages[$printer] = $data['init_pages_counter'];
- }
+ $pages[$printer] ??= $data['init_pages_counter'];
if ($pages[$printer] < $data['pages']) {
$pages_printed += $data['pages'] - $pages[$printer];
$nb_pages_printed++;
From 729aea55699fcfe7cce0286e01f6b6e71cb00596 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Tue, 8 Sep 2026 14:32:39 +0200
Subject: [PATCH 04/11] fix: Change_Item where clause
---
inc/change_item.class.php | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/inc/change_item.class.php b/inc/change_item.class.php
index 36140f55..e6ed3c5c 100644
--- a/inc/change_item.class.php
+++ b/inc/change_item.class.php
@@ -161,34 +161,35 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$dbu = new DbUtils();
- $restrict = '';
+ $restrict = [];
$order = '';
switch ($item->getType()) {
case 'User':
- $restrict = "(`glpi_changes_users`.`users_id` = '" . $item->getID() . "')";
+ $restrict = ['glpi_changes_users.users_id' => $item->getID()];
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Supplier':
- $restrict = "(`glpi_changes_suppliers`.`suppliers_id` = '" . $item->getID() . "')";
+ $restrict = ['glpi_changes_suppliers.suppliers_id' => $item->getID()];
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Group':
if ($tree) {
- $restrict = 'IN (' . implode(',', $dbu->getSonsOf('glpi_groups', $item->getID())) . ')';
+ $restrict = ['glpi_changes_groups.groups_id' => $dbu->getSonsOf('glpi_groups', $item->getID())];
} else {
- $restrict = "='" . $item->getID() . "'";
+ $restrict = ['glpi_changes_groups.groups_id' => $item->getID()];
}
- $restrict = "(`glpi_changes_groups`.`groups_id` $restrict
- AND `glpi_changes_groups`.`type` = " . CommonITILActor::REQUESTER . ')';
+ $restrict['glpi_changes_groups.type'] = CommonITILActor::REQUESTER;
$order = '`glpi_changes`.`date_mod` DESC';
break;
default:
- $restrict = "(`items_id` = '" . $item->getID() . "'
- AND `itemtype` = '" . $item->getType() . "')";
+ $restrict = [
+ 'glpi_changes_items.items_id' => $item->getID(),
+ 'glpi_changes_items.itemtype' => $item->getType(),
+ ];
$order = '`glpi_changes`.`date_mod` DESC';
break;
}
@@ -225,7 +226,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
'DISTINCT' => true,
'FROM' => 'glpi_changes',
'LEFT JOIN' => $LEFT_JOIN,
- 'WHERE' => [$restrict] + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
+ 'WHERE' => $restrict + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
'ORDER' => $order,
'LIMIT' => (int) $_SESSION['glpilist_limit'],
];
From f7996eb057ae361821c8d77a2b382de2dc2108e4 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Tue, 8 Sep 2026 15:53:25 +0200
Subject: [PATCH 05/11] Revert "fix: Change_Item where clause"
This reverts commit b3ab332d6180c77ac3b39cf26471d72b583d4187.
---
inc/change_item.class.php | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/inc/change_item.class.php b/inc/change_item.class.php
index e6ed3c5c..36140f55 100644
--- a/inc/change_item.class.php
+++ b/inc/change_item.class.php
@@ -161,35 +161,34 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$dbu = new DbUtils();
- $restrict = [];
+ $restrict = '';
$order = '';
switch ($item->getType()) {
case 'User':
- $restrict = ['glpi_changes_users.users_id' => $item->getID()];
+ $restrict = "(`glpi_changes_users`.`users_id` = '" . $item->getID() . "')";
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Supplier':
- $restrict = ['glpi_changes_suppliers.suppliers_id' => $item->getID()];
+ $restrict = "(`glpi_changes_suppliers`.`suppliers_id` = '" . $item->getID() . "')";
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Group':
if ($tree) {
- $restrict = ['glpi_changes_groups.groups_id' => $dbu->getSonsOf('glpi_groups', $item->getID())];
+ $restrict = 'IN (' . implode(',', $dbu->getSonsOf('glpi_groups', $item->getID())) . ')';
} else {
- $restrict = ['glpi_changes_groups.groups_id' => $item->getID()];
+ $restrict = "='" . $item->getID() . "'";
}
- $restrict['glpi_changes_groups.type'] = CommonITILActor::REQUESTER;
+ $restrict = "(`glpi_changes_groups`.`groups_id` $restrict
+ AND `glpi_changes_groups`.`type` = " . CommonITILActor::REQUESTER . ')';
$order = '`glpi_changes`.`date_mod` DESC';
break;
default:
- $restrict = [
- 'glpi_changes_items.items_id' => $item->getID(),
- 'glpi_changes_items.itemtype' => $item->getType(),
- ];
+ $restrict = "(`items_id` = '" . $item->getID() . "'
+ AND `itemtype` = '" . $item->getType() . "')";
$order = '`glpi_changes`.`date_mod` DESC';
break;
}
@@ -226,7 +225,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
'DISTINCT' => true,
'FROM' => 'glpi_changes',
'LEFT JOIN' => $LEFT_JOIN,
- 'WHERE' => $restrict + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
+ 'WHERE' => [$restrict] + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
'ORDER' => $order,
'LIMIT' => (int) $_SESSION['glpilist_limit'],
];
From e6992b63aac9c34d19a28117ea630aae285fbb64 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Tue, 8 Sep 2026 14:32:39 +0200
Subject: [PATCH 06/11] fix: Change_Item where clause
---
inc/change_item.class.php | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/inc/change_item.class.php b/inc/change_item.class.php
index 36140f55..e6ed3c5c 100644
--- a/inc/change_item.class.php
+++ b/inc/change_item.class.php
@@ -161,34 +161,35 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$dbu = new DbUtils();
- $restrict = '';
+ $restrict = [];
$order = '';
switch ($item->getType()) {
case 'User':
- $restrict = "(`glpi_changes_users`.`users_id` = '" . $item->getID() . "')";
+ $restrict = ['glpi_changes_users.users_id' => $item->getID()];
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Supplier':
- $restrict = "(`glpi_changes_suppliers`.`suppliers_id` = '" . $item->getID() . "')";
+ $restrict = ['glpi_changes_suppliers.suppliers_id' => $item->getID()];
$order = '`glpi_changes`.`date_mod` DESC';
break;
case 'Group':
if ($tree) {
- $restrict = 'IN (' . implode(',', $dbu->getSonsOf('glpi_groups', $item->getID())) . ')';
+ $restrict = ['glpi_changes_groups.groups_id' => $dbu->getSonsOf('glpi_groups', $item->getID())];
} else {
- $restrict = "='" . $item->getID() . "'";
+ $restrict = ['glpi_changes_groups.groups_id' => $item->getID()];
}
- $restrict = "(`glpi_changes_groups`.`groups_id` $restrict
- AND `glpi_changes_groups`.`type` = " . CommonITILActor::REQUESTER . ')';
+ $restrict['glpi_changes_groups.type'] = CommonITILActor::REQUESTER;
$order = '`glpi_changes`.`date_mod` DESC';
break;
default:
- $restrict = "(`items_id` = '" . $item->getID() . "'
- AND `itemtype` = '" . $item->getType() . "')";
+ $restrict = [
+ 'glpi_changes_items.items_id' => $item->getID(),
+ 'glpi_changes_items.itemtype' => $item->getType(),
+ ];
$order = '`glpi_changes`.`date_mod` DESC';
break;
}
@@ -225,7 +226,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
'DISTINCT' => true,
'FROM' => 'glpi_changes',
'LEFT JOIN' => $LEFT_JOIN,
- 'WHERE' => [$restrict] + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
+ 'WHERE' => $restrict + $dbu->getEntitiesRestrictCriteria('glpi_changes'),
'ORDER' => $order,
'LIMIT' => (int) $_SESSION['glpilist_limit'],
];
From 9881b6af846c26e81e4bfc892ed0f4f3bc1b957d Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Wed, 9 Sep 2026 08:50:42 +0200
Subject: [PATCH 07/11] fix: usage of deprecated methods triggering warnings
---
inc/item_problem.class.php | 36 +++++++++----------------
inc/item_ticket.class.php | 55 +++++++++++++++++---------------------
2 files changed, 37 insertions(+), 54 deletions(-)
diff --git a/inc/item_problem.class.php b/inc/item_problem.class.php
index 32a83683..dffb9b5a 100644
--- a/inc/item_problem.class.php
+++ b/inc/item_problem.class.php
@@ -155,8 +155,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
}
// Ajout de la restriction d'entités
- $entity_restrict = $dbu->getEntitiesRestrictRequest(
- '',
+ $entity_restrict = $dbu->getEntitiesRestrictCriteria(
$itemtable,
'',
'',
@@ -212,32 +211,34 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
$dbu = new DbUtils();
- $restrict = '';
+ $restrict = [];
$order = '';
switch ($item->getType()) {
case 'User':
- $restrict = "(`glpi_problems_users`.`users_id` = '" . $item->getID() . "')";
+ $restrict = ["glpi_problems_users.users_id" => $item->getID()];
$order = '`glpi_problems`.`date_mod` DESC';
break;
case 'Supplier':
- $restrict = "(`glpi_problems_suppliers`.`suppliers_id` = '" . $item->getID() . "')";
+ $restrict = ["glpi_problems_suppliers.suppliers_id" => $item->getID()];
$order = '`glpi_problems`.`date_mod` DESC';
break;
case 'Group':
if ($tree) {
- $restrict = 'IN (' . implode(',', $dbu->getSonsOf('glpi_groups', $item->getID())) . ')';
+ $restrict = ["glpi_groups_problems.groups_id" => $dbu->getSonsOf('glpi_groups', $item->getID())];
} else {
- $restrict = "='" . $item->getID() . "'";
+ $restrict = ["glpi_groups_problems.groups_id" => $item->getID()];
}
- $restrict = "(`glpi_groups_problems`.`groups_id` $restrict)";
+ //$restrict = "(`glpi_groups_problems`.`groups_id` $restrict)";
$order = '`glpi_problems`.`date_mod` DESC';
break;
default:
- $restrict = "(`items_id` = '" . $item->getID() . "'
- AND `itemtype` = '" . $item->getType() . "')";
+ $restrict = [
+ 'glpi_items_problems.items_id' => $item->getID(),
+ 'glpi_items_problems.itemtype' => $item->getType(),
+ ];
$order = '`glpi_problems`.`date_mod` DESC';
break;
}
@@ -294,25 +295,12 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
];
}
- $where_conditions = [];
-
- if (str_contains($restrict, 'IN (') || str_contains($restrict, 'AND') || str_contains($restrict, 'OR')) {
- $where_conditions[] = new QueryExpression($restrict);
- } else {
- $where_conditions[] = new QueryExpression($restrict);
- }
-
- $entity_restrict = $dbu->getEntitiesRestrictRequest('', 'glpi_problems');
- if (!empty($entity_restrict)) {
- $where_conditions[] = new QueryExpression($entity_restrict);
- }
-
$query_params = [
'SELECT' => $select_fields,
'DISTINCT' => true,
'FROM' => 'glpi_problems',
'LEFT JOIN' => $left_joins,
- 'WHERE' => $where_conditions,
+ 'WHERE' => $restrict + $dbu->getEntitiesRestrictCriteria('glpi_problems'),
'ORDER' => $order,
'LIMIT' => intval($_SESSION['glpilist_limit']),
];
diff --git a/inc/item_ticket.class.php b/inc/item_ticket.class.php
index e42b7128..7ba809ea 100644
--- a/inc/item_ticket.class.php
+++ b/inc/item_ticket.class.php
@@ -230,46 +230,54 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
return false;
}
- $restrict = '';
+ $restrict = [];
$order = '';
switch ($item->getType()) {
case 'User':
- $restrict = "(`glpi_tickets_users`.`users_id` = '" . $item->getID() . "'
- AND `glpi_tickets_users`.`type` = " . CommonITILActor::REQUESTER . ')';
+ $restrict = [
+ 'glpi_tickets_users.users_id' => $item->getID(),
+ 'glpi_tickets_users.type' => CommonITILActor::REQUESTER,
+ ];
$order = '`glpi_tickets`.`time_to_resolve` DESC';
break;
case 'SLA':
- $restrict = "(`slas_id` = '" . $item->getID() . "')";
+ $restrict = ['slas_id' => $item->getID()];
$order = '`glpi_tickets`.`time_to_resolve` DESC';
break;
case 'Supplier':
- $restrict = "(`glpi_suppliers_tickets`.`suppliers_id` = '" . $item->getID() . "'
- AND `glpi_suppliers_tickets`.`type` = " . CommonITILActor::ASSIGN . ')';
+ $restrict = [
+ 'glpi_suppliers_tickets.suppliers_id' => $item->getID(),
+ 'glpi_suppliers_tickets.type' => CommonITILActor::ASSIGN,
+ ];
$order = '`glpi_tickets`.`date_mod` DESC';
break;
case 'Group':
if ($tree) {
- $restrict = 'IN (' . implode(',', $dbu->getSonsOf('glpi_groups', $item->getID())) . ')';
+ $restrict = ['glpi_groups_tickets.groups_id' => $dbu->getSonsOf('glpi_groups', $item->getID())];
} else {
- $restrict = "='" . $item->getID() . "'";
+ $restrict = ['glpi_groups_tickets.groups_id' => $item->getID()];
}
- $restrict = "(`glpi_groups_tickets`.`groups_id` $restrict
- AND `glpi_groups_tickets`.`type` = " . CommonITILActor::REQUESTER . ')';
+ $restrict['glpi_groups_tickets.type'] = CommonITILActor::REQUESTER;
$order = '`glpi_tickets`.`date_mod` DESC';
break;
default:
- $restrict = "(`glpi_items_tickets`.`items_id` = '" . $item->getID() . "' " .
- " AND `glpi_items_tickets`.`itemtype` = '" . $item->getType() . "')";
+ $restrict = [
+ 'glpi_items_tickets.items_id' => $item->getID(),
+ 'glpi_items_tickets.itemtype' => $item->getType(),
+ ];
// you can only see your tickets
if (!Session::haveRight('ticket', Ticket::READALL)) {
- $restrict .= " AND (`glpi_tickets`.`users_id_recipient` = '" . Session::getLoginUserID() . "'
- OR (`glpi_tickets_users`.`tickets_id` = '" . $item->getID() . "'
- AND `glpi_tickets_users`.`users_id`
- = '" . Session::getLoginUserID() . "'))";
+ $restrict['OR'] = [
+ 'glpi_tickets.users_id_recipient' => Session::getLoginUserID(),
+ [
+ 'glpi_tickets_users.tickets_id' => $item->getID(),
+ 'glpi_tickets_users.users_id' => Session::getLoginUserID(),
+ ],
+ ];
}
$order = '`glpi_tickets`.`date_mod` DESC';
}
@@ -332,25 +340,12 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item, $tr
];
}
- $where_conditions = [];
-
- if (str_contains($restrict, 'OR') || str_contains($restrict, 'AND')) {
- $where_conditions[] = new QueryExpression($restrict);
- } else {
- $where_conditions[] = $restrict;
- }
-
- $entity_restrict = $dbu->getEntitiesRestrictRequest('', 'glpi_tickets');
- if (!empty($entity_restrict)) {
- $where_conditions[] = new QueryExpression($entity_restrict);
- }
-
$query_params = [
'SELECT' => $select_fields,
'DISTINCT' => true,
'FROM' => 'glpi_tickets',
'LEFT JOIN' => $left_joins,
- 'WHERE' => $where_conditions,
+ 'WHERE' => $restrict + $dbu->getEntitiesRestrictCriteria('glpi_tickets'),
'ORDER' => $order,
'LIMIT' => intval($_SESSION['glpilist_limit']),
];
From 125b4a5adb8d4192418ce97c68fca69d35006974 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Fri, 11 Sep 2026 15:47:29 +0200
Subject: [PATCH 08/11] fix: set default language to avoid 500 error if user
has no defined language
---
inc/user.class.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/inc/user.class.php b/inc/user.class.php
index 61e05357..6935208d 100644
--- a/inc/user.class.php
+++ b/inc/user.class.php
@@ -153,7 +153,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, User $item)
'' . sprintf(
__s('%1$s: %2$s'),
__s('Language') . ' ',
- Dropdown::getLanguageName($item->fields['language']),
+ Dropdown::getLanguageName($item->fields['language'] ?? "en_GB"),
),
);
From c5f857e9ce3dff23be33d901d7dfe906ba7af4b2 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Fri, 11 Sep 2026 15:48:20 +0200
Subject: [PATCH 09/11] fix: several pdf generation errors
---
inc/item_problem.class.php | 2 +-
inc/knowbaseitem.class.php | 13 ++++++++++---
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/inc/item_problem.class.php b/inc/item_problem.class.php
index dffb9b5a..e9676fe8 100644
--- a/inc/item_problem.class.php
+++ b/inc/item_problem.class.php
@@ -163,7 +163,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
);
if (!empty($entity_restrict)) {
- $query_params['WHERE'][] = new QueryExpression($entity_restrict);
+ $query_params['WHERE'] += $entity_restrict;
}
$result_linked = $DB->request($query_params);
diff --git a/inc/knowbaseitem.class.php b/inc/knowbaseitem.class.php
index 677065bc..daf68484 100644
--- a/inc/knowbaseitem.class.php
+++ b/inc/knowbaseitem.class.php
@@ -30,6 +30,8 @@
* --------------------------------------------------------------------------
*/
+use Glpi\Form\ServiceCatalog\ServiceCatalog;
+
class PluginPdfKnowbaseItem extends PluginPdfCommon
{
public static string $rightname = 'plugin_pdf';
@@ -47,6 +49,11 @@ public function defineAllTabsPDF($options = [])
unset($onglets['KnowbaseItemTranslation$1']);
unset($onglets['KnowbaseItem_Revision$1']);
+ $this->obj->addStandardTab(Document_Item::class, $onglets, $options);
+ $this->obj->addStandardTab(ServiceCatalog::class, $onglets, $options);
+ $this->obj->addStandardTab(Log::class, $onglets, $options);
+ $this->obj->addStandardTab(KnowbaseItem_Comment::class, $onglets, $options);
+
return $onglets;
}
@@ -63,11 +70,11 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, KnowbaseItem $item)
return false;
}
- $knowbaseitemcategories_id = $item->getField('knowbaseitemcategories_id');
+ $forms_categories_id = $item->getField('forms_categories_id');
$fullcategoryname
= Toolbox::stripTags($dbu->getTreeValueCompleteName(
- 'glpi_knowbaseitemcategories',
- $knowbaseitemcategories_id,
+ 'glpi_forms_categories',
+ (int) $forms_categories_id,
));
$question
From e251bc41c9144fd518604270e2334250e498f160 Mon Sep 17 00:00:00 2001
From: Julien Durand
Date: Mon, 14 Sep 2026 09:28:12 +0200
Subject: [PATCH 10/11] chore: rector
---
inc/item_problem.class.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/inc/item_problem.class.php b/inc/item_problem.class.php
index e9676fe8..f086fa57 100644
--- a/inc/item_problem.class.php
+++ b/inc/item_problem.class.php
@@ -30,7 +30,7 @@
* --------------------------------------------------------------------------
*/
-use Glpi\DBAL\QueryExpression;
+
/**
* -------------------------------------------------------------------------
@@ -162,7 +162,7 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
$item->maybeRecursive(),
);
- if (!empty($entity_restrict)) {
+ if ($entity_restrict !== []) {
$query_params['WHERE'] += $entity_restrict;
}
From d7b20fe998e6cfed4c64be8178aa1b7b3bd0109a Mon Sep 17 00:00:00 2001
From: Julien DURAND
Date: Tue, 6 Oct 2026 08:45:03 +0200
Subject: [PATCH 11/11] fix: pdf display with tcpdf (#93)
* fix: pdf display with tcpdf
* fix: header display
Co-authored-by: Romain B. <8530352+Rom1-B@users.noreply.github.com>
* fix: word not spliting if it contains no delimiter
If a word is too long and has no delimiter, it will overflow
Co-authored-by: Romain B. <8530352+Rom1-B@users.noreply.github.com>
* fix: header logo display
* chore: Add unit tests
* chore: changelog
---------
Co-authored-by: Romain B. <8530352+Rom1-B@users.noreply.github.com>
---
CHANGELOG.md | 1 +
inc/document.class.php | 2 +-
inc/simplepdf.class.php | 119 ++++++++++++++++++++++++++++++++++++----
phpunit.xml | 18 ++++++
tests/SimplePDFTest.php | 100 +++++++++++++++++++++++++++++++++
tests/bootstrap.php | 40 ++++++++++++++
6 files changed, 269 insertions(+), 11 deletions(-)
create mode 100644 phpunit.xml
create mode 100644 tests/SimplePDFTest.php
create mode 100644 tests/bootstrap.php
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7c49bcd9..c3f84d39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
+- Broken display in PDF since TCPDF 7
- Dependencies conflicts with core
- Internal server error when generating appliance asset pdf
- CI: fix Psalm cache directory, declare a unique composer autoloader suffix
diff --git a/inc/document.class.php b/inc/document.class.php
index ad67286c..0b2d7eb5 100644
--- a/inc/document.class.php
+++ b/inc/document.class.php
@@ -77,7 +77,7 @@ public static function pdfForItem(PluginPdfSimplePDF $pdf, CommonDBTM $item)
}
$pdf->displayTitle($title);
- $pdf->setColumnsSize(20, 15, 10, 10, 10, 8, 20, 7);
+ $pdf->setColumnsSize(18, 14, 9, 9, 9, 13, 17, 11);
$pdf->displayTitle(
__s('Name'),
__s('Entity'),
diff --git a/inc/simplepdf.class.php b/inc/simplepdf.class.php
index b2370ff0..981778b2 100644
--- a/inc/simplepdf.class.php
+++ b/inc/simplepdf.class.php
@@ -35,6 +35,13 @@
//use TCPDF;
define('K_PATH_IMAGES', '');
+
+if (!defined('K_ALLOWED_PATHS')) {
+ define('K_ALLOWED_PATHS', [
+ GLPI_PICTURE_DIR,
+ Plugin::getPhpDir('pdf') . '/public/pics',
+ ]);
+}
class PluginPdfSimplePDF
{
// Page orientation
@@ -95,7 +102,6 @@ public function __construct($format = 'A4', $orient = '')
//set auto page breaks
$pdf->SetAutoPageBreak(true, 15);
-
// For standard language
// set font
$pdf->SetFont($font, '', 8);
@@ -128,11 +134,12 @@ public function setHeader($msg)
!empty($hook['logo_path'])
&& $config->getField('use_branding_logo')
) {
- $this->pdf->SetHeaderData($hook['logo_path'], 15, $msg, '');
+ $logo_path = $hook['logo_path'];
} else {
- $path = Plugin::getPhpDir('pdf') . '/public/pics/';
- $this->pdf->SetHeaderData($path . 'fd_logo.png', 15, $msg, '');
+ $logo_path = Plugin::getPhpDir('pdf') . '/public/pics/fd_logo.png';
}
+
+ $this->pdf->SetHeaderData($logo_path, 15, $msg, '');
}
/**
@@ -225,6 +232,75 @@ public function displayBox($gray)
Toolbox::deprecated('Calling this function is deprecated');
}
+ /**
+ * Prepare a cell's content so it wraps inside its column instead of overflowing past it.
+ *
+ * @param $msg String cell content (plain text or HTML)
+ * @param $width Float usable width of the target column (mm)
+ **/
+ private function wrapCellContent($msg, $width)
+ {
+ $msg = (string) $msg;
+ if ($width <= 0 || str_contains($msg, '<')) {
+ return $msg;
+ }
+
+ // Check width word by word
+ $words = explode(' ', $msg);
+ foreach ($words as &$word) {
+ $word = $this->breakWordToFit($word, $width);
+ }
+ unset($word);
+
+ return implode(' ', $words);
+ }
+
+ /**
+ * Insert the minimum number of breakable spaces needed for a single word to fit a width.
+ *
+ * @param $word String single word (no spaces) to fit
+ * @param $width Float usable width of the target column (mm)
+ **/
+ private function breakWordToFit($word, $width)
+ {
+ if ($this->pdf->GetStringWidth($word) <= $width) {
+ return $word;
+ }
+
+ preg_match_all('/[\/\\\\_.@:-]/', $word, $matches, PREG_OFFSET_CAPTURE);
+ $breakpoints = array_map(static fn($match) => $match[1] + 1, $matches[0]);
+ if ($breakpoints === []) {
+ // No delimiter to split on: force a character-level break so the word still fits.
+ $result = '';
+ $chunk = '';
+ foreach (preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY) as $char) {
+ if ($chunk !== '' && $this->pdf->GetStringWidth($chunk . $char) > $width) {
+ $result .= $chunk . ' ';
+ $chunk = '';
+ }
+ $chunk .= $char;
+ }
+
+ return $result . $chunk;
+ }
+ $breakpoints[] = strlen($word);
+
+ $result = '';
+ $linestart = 0;
+ $lastfit = 0;
+ foreach ($breakpoints as $point) {
+ $fits = $this->pdf->GetStringWidth(substr($word, $linestart, $point - $linestart)) <= $width;
+ if (!$fits && $lastfit > $linestart) {
+ $result .= substr($word, $linestart, $lastfit - $linestart) . ' ';
+ $linestart = $lastfit;
+ }
+ $lastfit = $point;
+ }
+ $result .= substr($word, $linestart);
+
+ return $result;
+ }
+
/**
* display a row
*
@@ -236,16 +312,26 @@ public function displayBox($gray)
**/
private function displayInternal($gray, $padd, $defalign, $miny, $msgs)
{
+ $msgs = array_map(
+ fn($msg, $i) => $this->wrapCellContent($msg, ($this->colsw[$i] ?? 0) - (2 * $padd)),
+ $msgs,
+ array_keys($msgs),
+ );
+
$this->pdf->SetFillColor($gray, $gray, $gray);
$this->pdf->SetCellPadding($padd);
$max = $miny;
+ $rowy = $this->pdf->GetY();
+ $pageatstart = $this->pdf->getPage();
+ $measurey = $this->pdf->getMargins()['top'];
- /* dry run - compute max cell height */
+ /* Dry run - compute max cell height. */
$this->pdf->startTransaction();
$i = 0;
foreach ($msgs as $msg) {
if ($i < count($this->cols)) {
+ $this->pdf->SetXY($this->colsx[$i], $measurey);
$this->pdf->writeHTMLCell(
$this->colsw[$i], // $w (float) Cell width. If 0, the cell extends up to the right margin.
$miny, // $h (float) Cell minimum height. The cell extends automatically if needed.
@@ -253,23 +339,31 @@ private function displayInternal($gray, $padd, $defalign, $miny, $msgs)
'', // $y (float) upper-left corner Y coordinate
$msg, // $html (string) html text to print. Default value: empty string.
0, // $border (mixed) Indicates if borders must be drawn around the cell. The value can be a number:0: no border (default) 1: frame or a string containing some or all of the following characters (in any order):L: left T: top R: right B: bottom or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
- 0, // $ln (int) Indicates where the current position should go after the call. Possible values are:0: to the right (or left for RTL language) 1: to the beginning of the next line 2: below
+ 2, // $ln (int) Indicates where the current position should go after the call. Possible values are:0: to the right (or left for RTL language) 1: to the beginning of the next line 2: below
1, // $fill (boolean) Indicates if the cell background must be painted (true) or transparent (false).
true, // $reseth (boolean) if true reset the last cell height (default true).
self::LEFT, // $align (string) Allows to center or align the text. Possible values are:L : left align C : center R : right align '' : empty string : left for LTR or right for RTL
true, // $autopadding (boolean) if true, uses internal padding and automatically adjust it to account for line width.
);
- if ($this->pdf->getLastH() > $max) {
- $max = $this->pdf->getLastH();
+ $height = $this->pdf->GetY() - $measurey;
+ if ($this->pdf->getPage() === $pageatstart && $height > $max) {
+ $max = $height;
}
$i++;
} else {
break;
}
}
- $this->pdf = $this->pdf->rollbackTransaction();
+ $this->pdf->rollbackTransaction(true);
+
+ // Detect if content will go over page footer and add new page
+ if ($rowy + $max > $this->pdf->getPageHeight() - $this->pdf->getBreakMargin()) {
+ $this->pdf->AddPage();
+ $rowy = $this->pdf->GetY();
+ }
/* real run */
+ $pagebefore = $this->pdf->getPage();
$i = 0;
foreach ($msgs as $msg) {
if ($i < count($this->cols)) {
@@ -298,7 +392,12 @@ private function displayInternal($gray, $padd, $defalign, $miny, $msgs)
break;
}
}
- $this->pdf->SetY($this->pdf->GetY() + 1);
+ // TCPDF 7.0 doesn't update getLastH / $lastH, so we need to track the current height ourselves.
+ if ($this->pdf->getPage() === $pagebefore) {
+ $this->pdf->SetY($rowy + $max + 1);
+ } else {
+ $this->pdf->SetY($this->pdf->GetY() + 1);
+ }
}
/**
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 00000000..b827cdfc
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,18 @@
+
+
+
+ src
+
+
+
+
+
+ tests
+
+
+
diff --git a/tests/SimplePDFTest.php b/tests/SimplePDFTest.php
new file mode 100644
index 00000000..339a3b71
--- /dev/null
+++ b/tests/SimplePDFTest.php
@@ -0,0 +1,100 @@
+.
+ *
+ * @author Nelly Mahu-Lasson, Remi Collet, Teclib
+ * @author Teclib
+ * @copyright Copyright (c) 2009-2026 PDF plugin team
+ * @license AGPL License 3.0 or (at your option) any later version
+ * @link https://github.com/pluginsGLPI/pdf/
+ * @link http://www.glpi-project.org/
+ * @package pdf
+ * @since 2009
+ * http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ * --------------------------------------------------------------------------
+ */
+
+use Glpi\Tests\GLPITestCase;
+
+class SimplePDFTest extends GLPITestCase
+{
+ private function getStringWidth(PluginPdfSimplePDF $pdf, string $string): float
+ {
+ $property = new ReflectionProperty(PluginPdfSimplePDF::class, 'pdf');
+
+ return $property->getValue($pdf)->GetStringWidth($string);
+ }
+
+ public function testWrapCellContentLeavesHtmlUntouched(): void
+ {
+ $pdf = new PluginPdfSimplePDF();
+ $html = '' . str_repeat('a', 200) . ' ';
+
+ $this->assertSame($html, $this->callPrivateMethod($pdf, 'wrapCellContent', $html, 10));
+ }
+
+ public function testWrapCellContentLeavesContentUntouchedWhenWidthIsNotPositive(): void
+ {
+ $pdf = new PluginPdfSimplePDF();
+ $msg = str_repeat('a', 200);
+
+ $this->assertSame($msg, $this->callPrivateMethod($pdf, 'wrapCellContent', $msg, 0));
+ }
+
+ public function testBreakWordToFitLeavesWordUntouchedWhenItAlreadyFits(): void
+ {
+ $pdf = new PluginPdfSimplePDF();
+
+ $this->assertSame('short', $this->callPrivateMethod($pdf, 'breakWordToFit', 'short', 100));
+ }
+
+ public function testBreakWordToFitSplitsOnDelimiters(): void
+ {
+ $pdf = new PluginPdfSimplePDF();
+ $word = str_repeat('a', 20) . '/' . str_repeat('b', 20) . '-' . str_repeat('c', 20);
+ $width = $this->getStringWidth($pdf, str_repeat('a', 30));
+
+ $result = $this->callPrivateMethod($pdf, 'breakWordToFit', $word, $width);
+ $chunks = explode(' ', $result);
+
+ $this->assertSame($word, str_replace(' ', '', $result));
+ $this->assertGreaterThan(1, count($chunks));
+ foreach ($chunks as $chunk) {
+ $this->assertLessThanOrEqual($width, $this->getStringWidth($pdf, $chunk));
+ }
+ }
+
+ public function testBreakWordToFitFallsBackToCharacterSplitWithoutDelimiters(): void
+ {
+ $pdf = new PluginPdfSimplePDF();
+ $word = str_repeat('a', 200);
+ $width = $this->getStringWidth($pdf, str_repeat('a', 10));
+
+ $result = $this->callPrivateMethod($pdf, 'breakWordToFit', $word, $width);
+ $chunks = explode(' ', $result);
+
+ $this->assertSame($word, str_replace(' ', '', $result));
+ $this->assertGreaterThan(1, count($chunks));
+ foreach ($chunks as $chunk) {
+ $this->assertNotSame('', $chunk);
+ $this->assertLessThanOrEqual($width, $this->getStringWidth($pdf, $chunk));
+ }
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 00000000..f87da9ae
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,40 @@
+.
+ *
+ * @author Nelly Mahu-Lasson, Remi Collet, Teclib
+ * @copyright Copyright (c) 2009-2022 PDF plugin team
+ * @license AGPL License 3.0 or (at your option) any later version
+ * @link https://github.com/pluginsGLPI/pdf/
+ * @link http://www.glpi-project.org/
+ * @package pdf
+ * @since 2009
+ * http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ * --------------------------------------------------------------------------
+ */
+
+$current_plugin_folder = basename(dirname(__DIR__));
+
+require __DIR__ . '/../../../tests/bootstrap.php';
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+if (!Plugin::isPluginActive($current_plugin_folder)) {
+ throw new RuntimeException(sprintf('Plugin %s is not active in the test database', $current_plugin_folder));
+}