From b8c96bd499654f40dee363593f7aad6e8d9a8b08 Mon Sep 17 00:00:00 2001
From: Rom1-B <8530352+Rom1-B@users.noreply.github.com>
Date: Tue, 28 Jul 2026 09:34:52 +0200
Subject: [PATCH 1/2] Fix: port pending fixes from 10.0 bugfix branch to main
---
CHANGELOG.md | 12 ++++++++++++
inc/change.class.php | 31 +++++++++++--------------------
inc/change_item.class.php | 4 ++--
inc/changevalidation.class.php | 4 ++--
inc/item_problem.class.php | 8 ++++----
inc/problem.class.php | 2 +-
inc/simplepdf.class.php | 6 ++++--
inc/ticketvalidation.class.php | 4 ++--
8 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad7b5ef..8859b81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,18 @@ 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
+
+- Fixed approval comments rendering as raw HTML in PDF
+- Fixed PDF crash when exporting Problems with linked items lacking serial/inventory fields
+- Fixed Change and Problem description exported as a single unstructured text block
+- Fixed Change analysis and plan fields rendering as raw HTML in PDF
+- Fixed rich text content rendered as visible HTML tags and unformatted text in PDF exports
+- Fixed Change approval comments rendering as visible HTML entities in PDF exports
+- Fixed Changes linked items showing phantom empty entries for users with broad entity access
+
## [4.1.3] - 2026-06-24
### Fixed
diff --git a/inc/change.class.php b/inc/change.class.php
index f66e41a..1a6d8ac 100644
--- a/inc/change.class.php
+++ b/inc/change.class.php
@@ -298,7 +298,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Change $job)
$pdf->displayText(
'' . sprintf(__s('%1$s: %2$s') . '', __s('Description'), ''),
- Toolbox::stripTags($job->fields['content']),
+ $job->fields['content'],
1,
);
@@ -310,19 +310,15 @@ public static function pdfAnalysis(PluginPdfSimplePDF $pdf, Change $job)
$pdf->setColumnsSize(100);
$pdf->displayTitle('' . __s('Analysis') . '');
- $pdf->setColumnsSize(10, 90);
-
- $pdf->displayText(sprintf(
- __s('%1$s: %2$s'),
+ $pdf->displayText(
'' . __s('Impacts') . '',
$job->fields['impactcontent'],
- ));
+ );
- $pdf->displayText(sprintf(
- __s('%1$s: %2$s'),
+ $pdf->displayText(
'' . __s('Control list') . '',
$job->fields['controlistcontent'],
- ));
+ );
}
public static function pdfPlan(PluginPdfSimplePDF $pdf, Change $job)
@@ -330,25 +326,20 @@ public static function pdfPlan(PluginPdfSimplePDF $pdf, Change $job)
$pdf->setColumnsSize(100);
$pdf->displayTitle('' . __s('Plans') . '');
- $pdf->setColumnsSize(10, 90);
-
- $pdf->displayText(sprintf(
- __s('%1$s: %2$s'),
+ $pdf->displayText(
'' . __s('Deployment plan') . '',
$job->fields['rolloutplancontent'],
- ));
+ );
- $pdf->displayText(sprintf(
- __s('%1$s: %2$s'),
+ $pdf->displayText(
'' . __s('Backup plan') . '',
$job->fields['backoutplancontent'],
- ));
+ );
- $pdf->displayText(sprintf(
- __s('%1$s: %2$s'),
+ $pdf->displayText(
'' . __s('Checklist') . '',
$job->fields['checklistcontent'],
- ));
+ );
}
public static function pdfStat(PluginPdfSimplePDF $pdf, Change $job)
diff --git a/inc/change_item.class.php b/inc/change_item.class.php
index e6790b7..dca4a69 100644
--- a/inc/change_item.class.php
+++ b/inc/change_item.class.php
@@ -91,8 +91,8 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
$query = ['FIELDS' => [$itemtable . '.*', 'glpi_changes_items.id AS IDD',
'glpi_entities.id AS entity'],
- 'FROM' => 'glpi_changes_items',
- 'LEFT JOIN' => [$itemtable => ['FKEY' => [$itemtable => 'id',
+ 'FROM' => 'glpi_changes_items',
+ 'INNER JOIN' => [$itemtable => ['FKEY' => [$itemtable => 'id',
'glpi_changes_items' => 'items_id'],
'glpi_changes_items.itemtype' => $itemtype,
'glpi_changes_items.changes_id' => $instID]]];
diff --git a/inc/changevalidation.class.php b/inc/changevalidation.class.php
index 6b20670..2a8e713 100644
--- a/inc/changevalidation.class.php
+++ b/inc/changevalidation.class.php
@@ -92,10 +92,10 @@ public static function pdfForChange(PluginPdfSimplePDF $pdf, Change $change)
TicketValidation::getStatus($row['status']),
Html::convDateTime($row['submission_date']),
$dbu->getUserName($row['users_id']),
- trim($row['comment_submission']),
+ trim(html_entity_decode($row['comment_submission'] ?? '', ENT_QUOTES, 'UTF-8')),
Html::convDateTime($row['validation_date']),
$dbu->getUserName($row['users_id_validate']),
- trim($row['comment_validation']),
+ trim(html_entity_decode($row['comment_validation'] ?? '', ENT_QUOTES, 'UTF-8')),
);
}
}
diff --git a/inc/item_problem.class.php b/inc/item_problem.class.php
index 0a1bdc8..0ceb1fb 100644
--- a/inc/item_problem.class.php
+++ b/inc/item_problem.class.php
@@ -182,8 +182,8 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
Toolbox::stripTags(sprintf(__s('%1$s: %2$s'), $typename, $nb)),
Toolbox::stripTags($name),
Dropdown::getDropdownName('glpi_entities', $data['entity']),
- Toolbox::stripTags($data['serial']),
- Toolbox::stripTags($data['otherserial']),
+ Toolbox::stripTags($data['serial'] ?? ''),
+ Toolbox::stripTags($data['otherserial'] ?? ''),
$nb,
);
} else {
@@ -191,8 +191,8 @@ public static function pdfForProblem(PluginPdfSimplePDF $pdf, Problem $problem)
'',
Toolbox::stripTags($name),
Dropdown::getDropdownName('glpi_entities', $data['entity']),
- Toolbox::stripTags($data['serial']),
- Toolbox::stripTags($data['otherserial']),
+ Toolbox::stripTags($data['serial'] ?? ''),
+ Toolbox::stripTags($data['otherserial'] ?? ''),
$nb,
);
}
diff --git a/inc/problem.class.php b/inc/problem.class.php
index f2ce73b..2484950 100644
--- a/inc/problem.class.php
+++ b/inc/problem.class.php
@@ -298,7 +298,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Problem $job)
$pdf->displayText(
'' . sprintf(__s('%1$s: %2$s'), __s('Description') . '', ''),
- Toolbox::stripTags($job->fields['content']),
+ $job->fields['content'],
1,
);
diff --git a/inc/simplepdf.class.php b/inc/simplepdf.class.php
index 6b9d322..eb46c07 100644
--- a/inc/simplepdf.class.php
+++ b/inc/simplepdf.class.php
@@ -345,8 +345,10 @@ public function displayText($name, $content = '', $minline = 3, $maxline = 100)
$save = [$this->cols, $this->colsx, $this->colsw, $this->align];
$this->setColumnsSize(100);
- $text = $name . ' ' . $content;
- $content = RichText::getEnhancedHtml($text, ['text_maxsize' => 0]);
+
+ // Decode $content alone: mixing literal HTML from $name breaks isHtmlEncoded(), leaving GLPI entities (<) un-decoded and visible as text in TCPDF.
+ $decoded = RichText::getEnhancedHtml($content ?? '', ['text_maxsize' => 0]);
+ $content = preg_replace('/