Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../PluginsMakefile.mk
31 changes: 11 additions & 20 deletions inc/change.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Change $job)

$pdf->displayText(
'<b><i>' . sprintf(__s('%1$s: %2$s') . '</i></b>', __s('Description'), ''),
Toolbox::stripTags($job->fields['content']),
$job->fields['content'],
1,
);

Expand All @@ -310,45 +310,36 @@ public static function pdfAnalysis(PluginPdfSimplePDF $pdf, Change $job)
$pdf->setColumnsSize(100);
$pdf->displayTitle('<b>' . __s('Analysis') . '</b>');

$pdf->setColumnsSize(10, 90);

$pdf->displayText(sprintf(
__s('%1$s: %2$s'),
$pdf->displayText(
'<b><i>' . __s('Impacts') . '</i></b>',
$job->fields['impactcontent'],
));
);

$pdf->displayText(sprintf(
__s('%1$s: %2$s'),
$pdf->displayText(
'<b><i>' . __s('Control list') . '</i></b>',
$job->fields['controlistcontent'],
));
);
}

public static function pdfPlan(PluginPdfSimplePDF $pdf, Change $job)
{
$pdf->setColumnsSize(100);
$pdf->displayTitle('<b>' . __s('Plans') . '</b>');

$pdf->setColumnsSize(10, 90);

$pdf->displayText(sprintf(
__s('%1$s: %2$s'),
$pdf->displayText(
'<b><i>' . __s('Deployment plan') . '</i></b>',
$job->fields['rolloutplancontent'],
));
);

$pdf->displayText(sprintf(
__s('%1$s: %2$s'),
$pdf->displayText(
'<b><i>' . __s('Backup plan') . '</i></b>',
$job->fields['backoutplancontent'],
));
);

$pdf->displayText(sprintf(
__s('%1$s: %2$s'),
$pdf->displayText(
'<b><i>' . __s('Checklist') . '</i></b>',
$job->fields['checklistcontent'],
));
);
}

public static function pdfStat(PluginPdfSimplePDF $pdf, Change $job)
Expand Down
4 changes: 2 additions & 2 deletions inc/change_item.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]]];
Expand Down
4 changes: 2 additions & 2 deletions inc/changevalidation.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')),
);
}
}
Expand Down
1 change: 1 addition & 0 deletions inc/common.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function addStandardTab($itemtype, array &$ong, array $options)
$withtemplate = $options['withtemplate'];
}

// @phpstan-ignore-next-line function.impossibleType - is_numeric() kept for parity with CommonGLPI::addStandardTab(), whose $itemtype PHPDoc type makes it always false
if (!is_numeric($itemtype) && ($obj = $dbu->getItemForItemtype($itemtype)) && (method_exists($itemtype, 'displayTabContentForPDF'))) {
$titles = $obj->getTabNameForItem($this->obj, $withtemplate);
if (!is_array($titles)) {
Expand Down
8 changes: 4 additions & 4 deletions inc/item_problem.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,17 @@ 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 {
$pdf->displayLine(
'',
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,
);
}
Expand Down
2 changes: 1 addition & 1 deletion inc/problem.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public static function pdfMain(PluginPdfSimplePDF $pdf, Problem $job)

$pdf->displayText(
'<b><i>' . sprintf(__s('%1$s: %2$s'), __s('Description') . '</i></b>', ''),
Toolbox::stripTags($job->fields['content']),
$job->fields['content'],
1,
);

Expand Down
6 changes: 4 additions & 2 deletions inc/simplepdf.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 (&#60;) un-decoded and visible as text in TCPDF.
$decoded = RichText::getEnhancedHtml($content ?? '', ['text_maxsize' => 0]);
$content = preg_replace('/<script\b[^>]*>.*?<\/script>/is', '', $name . ' ' . $decoded);

// Decode HTML entities BEFORE searching for images
$content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
Expand Down
4 changes: 2 additions & 2 deletions inc/ticketvalidation.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ public static function pdfForTicket(PluginPdfSimplePDF $pdf, Ticket $ticket)
Html::convDateTime($row['validation_date']),
$dbu->getUserName($row['users_id_validate']),
);
$tmp = trim($row['comment_submission']);
$tmp = trim(html_entity_decode($row['comment_submission'] ?? '', ENT_QUOTES, 'UTF-8'));
$pdf->displayText('<b><i>' . sprintf(
__s('%1$s: %2$s'),
__s('Request comments') . '</i></b>',
'',
), (empty($tmp) ? __s('None') : $tmp), 1);

if ($row['validation_date']) {
$tmp = trim($row['comment_validation']);
$tmp = trim(html_entity_decode($row['comment_validation'] ?? '', ENT_QUOTES, 'UTF-8'));
$pdf->displayText(
'<b><i>' . sprintf(
__s('%1$s: %2$s'),
Expand Down