ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTestHTMLGenerator.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
30{
31 private function buildHtmlDocument($content_html, $style_html): string
32 {
33 return "
34 <html>
35 <head>
36 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
37 $style_html
38 </head>
39 <body>$content_html</body>
40 </html>
41 ";
42 }
43
49 private function makeHtmlDocument($content_html, $style_html): string
50 {
51 if (!is_string($content_html) || !strlen(trim($content_html))) {
52 return $content_html;
53 }
54
55 $html = $this->buildHtmlDocument($content_html, $style_html);
56
57 $dom = new DOMDocument("1.0", "utf-8");
58 if (!@$dom->loadHTML($html)) {
59 return $html;
60 }
61
62 $invalid_elements = [];
63
64 $script_elements = $dom->getElementsByTagName('script');
65 foreach ($script_elements as $elm) {
66 $invalid_elements[] = $elm;
67 }
68
69 foreach ($invalid_elements as $elm) {
70 $elm->parentNode->removeChild($elm);
71 }
72
73 // remove noprint elems as tcpdf will make empty pdf when hidden by css rules
74 $domX = new DomXPath($dom);
75 foreach ($domX->query("//*[contains(@class, 'noprint')]") as $node) {
76 $node->parentNode->removeChild($node);
77 }
78
79 $dom->encoding = 'UTF-8';
80
81 $content_to_replace = $this->generateImageDataSrces($dom);
82
83 $cleaned_html = $dom->saveHTML();
84
85 if (!$cleaned_html) {
86 return $html;
87 }
88
89 if ($content_to_replace === null) {
90 return $cleaned_html;
91 }
92
93 return str_replace(array_keys($content_to_replace), array_values($content_to_replace), $cleaned_html);
94 }
95
96 private function generateImageDataSrces(DOMDocument $dom): ?array
97 {
98 $content_to_replace = null;
99 $sources = [];
100 $image_file_names = [];
101 foreach ($dom->getElementsByTagName('img') as $elm) {
103 $src = $elm->getAttribute('src');
104 $original_content = $dom->saveHTML($elm);
105
106 if (array_key_exists($src, $sources)) {
107 $replacement_content = preg_replace('/src=[^\s]*/', "src='{$sources[$src]}'", $original_content);
108 $content_to_replace[$original_content] = $replacement_content;
109 continue;
110 }
111
112 if (stripos($src, ILIAS_HTTP_PATH) !== false
113 && stripos($src, 'assets') === false
114 && file_exists($src)) {
115 $src = ILIAS_HTTP_PATH . substr(ilWACSignedPath::signFile($src), 1);
116 }
117
118 try {
119 $image_raw_content = file_get_contents($src);
120 $image_file_names[$src] = ilFileUtils::ilTempnam();
121 file_put_contents($image_file_names[$src], $image_raw_content);
122 $image_content = base64_encode($image_raw_content);
123 $file_info = finfo_open(FILEINFO_MIME_TYPE);
124 $mime_type = finfo_file($file_info, $image_file_names[$src]);
125 $image_data = "data:{$mime_type};base64,{$image_content}";
126 $sources[$src] = $image_data;
127 $replacement_content = preg_replace('/src=[^\s]*/', "src='{$image_data}'", $original_content);
128 $content_to_replace[$original_content] = $replacement_content;
129 } catch (Exception $e) {
130
131 }
132 }
133
134 foreach ($image_file_names as $image_file_name) {
135 unlink($image_file_name);
136 }
137
138 return $content_to_replace;
139 }
140
141 public function generateHTML(string $content, string $filename)
142 {
143 file_put_contents($filename, $this->preprocessHTML($content));
144 return true;
145 }
146
147 private function preprocessHTML(string $html): string
148 {
149 return $this->makeHtmlDocument($html, '<style>' . $this->getCssContent() . '</style>');
150 }
151
152 private function getTemplatePath($a_filename, $module_path = 'components/ILIAS/Test/'): string
153 {
154 $fname = '';
155 if (ilStyleDefinition::getCurrentSkin() !== 'default') {
156 $fname = './Customizing/skin/' .
157 ilStyleDefinition::getCurrentSkin() . '/' . $module_path . basename($a_filename);
158 }
159
160 if ($fname == '' || !file_exists($fname)) {
161 $fname = './' . $module_path . 'assets/css/' . basename($a_filename);
162 }
163 return $fname;
164 }
165
166 private function getCssContent(): string
167 {
168 $css_content = file_get_contents($this->getTemplatePath('delos.css', ''));
169 $css_content .= ' html, body { overflow: auto; } body { padding: 1rem; }';
170
171 return $css_content;
172 }
173}
$filename
Definition: buildRTE.php:78
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static getCurrentSkin()
get the current skin use always this function instead of getting the account's skin the current skin ...
Class that handles PDF generation for test and assessment.
buildHtmlDocument($content_html, $style_html)
generateHTML(string $content, string $filename)
getTemplatePath($a_filename, $module_path='components/ILIAS/Test/')
makeHtmlDocument($content_html, $style_html)
static signFile(string $path_to_file)