diff --git a/CHANGELOG.md b/CHANGELOG.md index c5290f6..48c52fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - GLPI 11 compatibility +### Fixed + +- Fixed table formatting and border in PDF +- Fixed table cell size in PDF generation + ## [4.0.2] - 2025-09-30 - Fix missing images in exported Knowledge Base PDFs diff --git a/inc/simplepdf.class.php b/inc/simplepdf.class.php index f1406f1..628e297 100644 --- a/inc/simplepdf.class.php +++ b/inc/simplepdf.class.php @@ -32,36 +32,6 @@ use Glpi\RichText\RichText; -/** - * ------------------------------------------------------------------------- - * LICENSE - * - * This file is part of PDF plugin for GLPI. - * - * PDF is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * PDF is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Reports. If not, see . - * - * @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 - * -------------------------------------------------------------------------- - */ - //use TCPDF; define('K_PATH_IMAGES', ''); @@ -376,11 +346,29 @@ public function displayText($name, $content = '', $minline = 3, $maxline = 100) $this->setColumnsSize(100); $text = $name . ' ' . $content; - $content = RichText::getEnhancedHtml($text); - if (!preg_match("//", $content) && !preg_match('/

/', $content)) { - $content = nl2br($content); + $content = RichText::getEnhancedHtml($text, ['text_maxsize' => 0]); + + // Split content by tables, keeping tables in the result + $segments = preg_split('/(]*>.*?<\/table>)/is', $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + + // Process segments and rebuild content + $formatted_content = ''; + foreach ($segments as $segment) { + if (str_contains($segment, 'cleanTableHtml($segment); + $formatted_content .= $segment; + } else { + // Apply nl2br only to text segments + if (!str_contains($segment, '')) { + $segment = nl2br($segment); + } + $formatted_content .= $segment; + } } - $this->displayInternal(240, 0.5, self::LEFT, $minline * 5, [$content]); + + $this->displayInternal(240, 0.5, self::LEFT, $minline * 5, [$formatted_content]); + /* Restore */ [$this->cols, $this->colsx, $this->colsw, $this->align, ] = $save; } @@ -395,6 +383,48 @@ public function displaySpace($nb = 1) $this->pdf->Ln(4 * $nb); } + /** + * Clean table HTML for proper PDF rendering + * Removes problematic attributes and styles that cause tables to overflow + * + * @param string $html Table HTML code + * @return string Cleaned HTML + */ + private function cleanTableHtml($html) + { + // Remove colgroup entirely (causes fixed widths) + $html = preg_replace('/]*>.*?<\/colgroup>/is', '', $html); + + // Remove table-layout:fixed style (prevents auto-sizing) + $html = preg_replace('/table-layout\s*:\s*fixed\s*;?/i', '', $html); + + // Remove ALL width styles from elements (including px, %, em, etc.) + $html = preg_replace('/\bwidth\s*:\s*[^;"\'>]+;?/i', '', $html); + + // Remove ALL height styles from elements + $html = preg_replace('/\bheight\s*:\s*[^;"\'>]+;?/i', '', $html); + + // Remove width attributes from any tag + $html = preg_replace('/(<[^>]+)\s+width\s*=\s*["\']?[^"\'\s>]+["\']?/i', '$1', $html); + + // Remove height attributes from any tag + $html = preg_replace('/(<[^>]+)\s+height\s*=\s*["\']?[^"\'\s>]+["\']?/i', '$1', $html); + + // Clean up empty style attributes and double spaces + $html = preg_replace('/\s+style\s*=\s*["\'][\s]*["\']/', '', $html); + $html = preg_replace('/\s+/', ' ', $html); + + // Add border to table if missing (for visibility) + if (!preg_match('/border\s*=\s*["\']?[1-9]/i', $html)) { + $html = preg_replace('/]*)>/i', '', $html, 1); + + return $html; + } + /** * Display an image *