ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilTestHTMLGenerator.php
Go to the documentation of this file.
1 <?php
2 
19 declare(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 }
makeHtmlDocument($content_html, $style_html)
generateHTML(string $content, string $filename)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static getCurrentSkin()
get the current skin use always this function instead of getting the account&#39;s skin the current skin ...
getTemplatePath($a_filename, $module_path='components/ILIAS/Test/')
$filename
Definition: buildRTE.php:78
Class that handles PDF generation for test and assessment.
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static signFile(string $path_to_file)
buildHtmlDocument($content_html, $style_html)