1 | <?php |
||||||
2 | /* See license terms in /license.txt */ |
||||||
3 | |||||||
4 | use Chamilo\CoreBundle\Component\Utils\ChamiloApi; |
||||||
5 | |||||||
6 | /** |
||||||
7 | * Class PDF. |
||||||
8 | */ |
||||||
9 | class PDF |
||||||
10 | { |
||||||
11 | /** @var mPDF */ |
||||||
12 | public $pdf; |
||||||
13 | public $custom_header = []; |
||||||
14 | public $custom_footer = []; |
||||||
15 | public $params = []; |
||||||
16 | public $template; |
||||||
17 | |||||||
18 | /** |
||||||
19 | * Creates the mPDF object. |
||||||
20 | * |
||||||
21 | * @param string $pageFormat format A4 A4-L see |
||||||
22 | * http://mpdf1.com/manual/index.php?tid=184&searchstring=format |
||||||
23 | * @param string $orientation orientation "P" = Portrait "L" = Landscape |
||||||
24 | * @param array $params |
||||||
25 | * @param Template $template |
||||||
26 | */ |
||||||
27 | public function __construct( |
||||||
28 | $pageFormat = 'A4', |
||||||
29 | $orientation = 'P', |
||||||
30 | $params = [], |
||||||
31 | $template = null |
||||||
32 | ) { |
||||||
33 | $this->template = $template; |
||||||
34 | /* More info @ http://mpdf1.com/manual/index.php?tid=184&searchstring=mPDF */ |
||||||
35 | if (!in_array($orientation, ['P', 'L'])) { |
||||||
36 | $orientation = 'P'; |
||||||
37 | } |
||||||
38 | //left, right, top, bottom, margin_header, margin footer |
||||||
39 | |||||||
40 | $params['left'] = isset($params['left']) ? $params['left'] : 15; |
||||||
41 | $params['right'] = isset($params['right']) ? $params['right'] : 15; |
||||||
42 | $params['top'] = isset($params['top']) ? $params['top'] : 30; |
||||||
43 | $params['bottom'] = isset($params['bottom']) ? $params['bottom'] : 30; |
||||||
44 | $params['margin_footer'] = isset($params['margin_footer']) ? $params['margin_footer'] : 8; |
||||||
45 | |||||||
46 | $this->params['filename'] = isset($params['filename']) ? $params['filename'] : api_get_local_time(); |
||||||
47 | $this->params['pdf_title'] = isset($params['pdf_title']) ? $params['pdf_title'] : ''; |
||||||
48 | $this->params['course_info'] = isset($params['course_info']) ? $params['course_info'] : api_get_course_info(); |
||||||
49 | $this->params['session_info'] = isset($params['session_info']) ? $params['session_info'] : api_get_session_info(api_get_session_id()); |
||||||
50 | $this->params['course_code'] = isset($params['course_code']) ? $params['course_code'] : api_get_course_id(); |
||||||
51 | $this->params['add_signatures'] = isset($params['add_signatures']) ? $params['add_signatures'] : []; |
||||||
52 | $this->params['show_real_course_teachers'] = isset($params['show_real_course_teachers']) ? $params['show_real_course_teachers'] : false; |
||||||
53 | $this->params['student_info'] = isset($params['student_info']) ? $params['student_info'] : false; |
||||||
54 | $this->params['show_grade_generated_date'] = isset($params['show_grade_generated_date']) ? $params['show_grade_generated_date'] : false; |
||||||
55 | $this->params['show_teacher_as_myself'] = isset($params['show_teacher_as_myself']) ? $params['show_teacher_as_myself'] : true; |
||||||
56 | $localTime = api_get_local_time(); |
||||||
57 | $this->params['pdf_date'] = isset($params['pdf_date']) ? $params['pdf_date'] : api_format_date($localTime, DATE_TIME_FORMAT_LONG); |
||||||
58 | $this->params['pdf_date_only'] = isset($params['pdf_date']) ? $params['pdf_date'] : api_format_date($localTime, DATE_FORMAT_LONG); |
||||||
59 | |||||||
60 | @$this->pdf = new mPDF( |
||||||
61 | 'UTF-8', |
||||||
62 | $pageFormat, |
||||||
63 | '', |
||||||
64 | '', |
||||||
65 | $params['left'], |
||||||
66 | $params['right'], |
||||||
67 | $params['top'], |
||||||
68 | $params['bottom'], |
||||||
69 | 8, |
||||||
70 | 8, |
||||||
71 | $orientation |
||||||
72 | ); |
||||||
73 | |||||||
74 | $this->pdf->margin_footer = $params['margin_footer']; |
||||||
75 | |||||||
76 | // Default value is 96 set in the mpdf library file config.php |
||||||
77 | $value = api_get_configuration_value('pdf_img_dpi'); |
||||||
78 | if (!empty($value)) { |
||||||
79 | $this->pdf->img_dpi = (int) $value; |
||||||
80 | } |
||||||
81 | } |
||||||
82 | |||||||
83 | /** |
||||||
84 | * Export the given HTML to PDF, using a global template. |
||||||
85 | * |
||||||
86 | * @uses \export/table_pdf.tpl |
||||||
87 | * |
||||||
88 | * @param string $content |
||||||
89 | * @param bool|false $saveToFile |
||||||
90 | * @param bool|false $returnHtml |
||||||
91 | * @param bool $addDefaultCss (bootstrap/default/base.css) |
||||||
92 | * @param array |
||||||
93 | * |
||||||
94 | * @return string |
||||||
95 | */ |
||||||
96 | public function html_to_pdf_with_template( |
||||||
97 | $content, |
||||||
98 | $saveToFile = false, |
||||||
99 | $returnHtml = false, |
||||||
100 | $addDefaultCss = false, |
||||||
101 | $extraRows = [] |
||||||
102 | ) { |
||||||
103 | if (empty($this->template)) { |
||||||
104 | $tpl = new Template('', false, false, false, false, true, false); |
||||||
105 | } else { |
||||||
106 | $tpl = $this->template; |
||||||
107 | } |
||||||
108 | |||||||
109 | // Assignments |
||||||
110 | $tpl->assign('pdf_content', $content); |
||||||
111 | |||||||
112 | // Showing only the current teacher/admin instead the all teacher list name see BT#4080 |
||||||
113 | $teacher_list = null; |
||||||
114 | if (isset($this->params['show_real_course_teachers']) && |
||||||
115 | $this->params['show_real_course_teachers'] |
||||||
116 | ) { |
||||||
117 | if (isset($this->params['session_info']) && |
||||||
118 | !empty($this->params['session_info']) |
||||||
119 | ) { |
||||||
120 | $teacher_list = SessionManager::getCoachesByCourseSessionToString( |
||||||
121 | $this->params['session_info']['id'], |
||||||
122 | $this->params['course_info']['real_id'] |
||||||
123 | ); |
||||||
124 | } else { |
||||||
125 | $teacher_list = CourseManager::getTeacherListFromCourseCodeToString( |
||||||
126 | $this->params['course_code'] |
||||||
127 | ); |
||||||
128 | } |
||||||
129 | } else { |
||||||
130 | $user_info = api_get_user_info(); |
||||||
131 | if ($this->params['show_teacher_as_myself']) { |
||||||
132 | $teacher_list = $user_info['complete_name']; |
||||||
133 | } |
||||||
134 | } |
||||||
135 | |||||||
136 | $tpl->assign('pdf_course', $this->params['course_code']); |
||||||
137 | $tpl->assign('pdf_course_info', $this->params['course_info']); |
||||||
138 | $tpl->assign('pdf_session_info', $this->params['session_info']); |
||||||
139 | $tpl->assign('pdf_date', $this->params['pdf_date']); |
||||||
140 | $tpl->assign('pdf_date_only', $this->params['pdf_date_only']); |
||||||
141 | $tpl->assign('pdf_teachers', $teacher_list); |
||||||
142 | $tpl->assign('pdf_title', $this->params['pdf_title']); |
||||||
143 | $tpl->assign('pdf_student_info', $this->params['student_info']); |
||||||
144 | $tpl->assign('show_grade_generated_date', $this->params['show_grade_generated_date']); |
||||||
145 | $tpl->assign('add_signatures', $this->params['add_signatures']); |
||||||
146 | $tpl->assign('extra_rows', $extraRows); |
||||||
147 | |||||||
148 | // Getting template |
||||||
149 | $tableTemplate = $tpl->get_template('export/table_pdf.tpl'); |
||||||
150 | $html = $tpl->fetch($tableTemplate); |
||||||
151 | $html = api_utf8_encode($html); |
||||||
152 | |||||||
153 | if ($returnHtml) { |
||||||
154 | return $html; |
||||||
155 | } |
||||||
156 | |||||||
157 | $css = api_get_print_css(); |
||||||
158 | |||||||
159 | self::content_to_pdf( |
||||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
160 | $html, |
||||||
161 | $css, |
||||||
162 | $this->params['filename'], |
||||||
163 | $this->params['course_code'], |
||||||
164 | 'D', |
||||||
165 | $saveToFile, |
||||||
166 | null, |
||||||
167 | $returnHtml, |
||||||
168 | $addDefaultCss |
||||||
169 | ); |
||||||
170 | } |
||||||
171 | |||||||
172 | /** |
||||||
173 | * Converts HTML files to PDF. |
||||||
174 | * |
||||||
175 | * @param mixed $html_file_array could be an html file path or an array |
||||||
176 | * with paths example: |
||||||
177 | * /var/www/myfile.html or array('/myfile.html','myotherfile.html') or |
||||||
178 | * even an indexed array with both 'title' and 'path' indexes |
||||||
179 | * for each element like |
||||||
180 | * array( |
||||||
181 | * 0 => array('title'=>'Hello','path'=>'file.html'), |
||||||
182 | * 1 => array('title'=>'Bye','path'=>'file2.html') |
||||||
183 | * ); |
||||||
184 | * @param string $pdf_name pdf name |
||||||
185 | * @param null $course_code (if you are using html that are located |
||||||
186 | * in the document tool you must provide this) |
||||||
187 | * @param bool $print_title add title |
||||||
188 | * @param bool $complete_style show header and footer if true |
||||||
189 | * @param bool $addStyle |
||||||
190 | * @param string $mainTitle |
||||||
191 | * @param bool $generateToFile Optional. When it is TRUE, then the output file is move to app/cache |
||||||
192 | * |
||||||
193 | * @throws \MpdfException |
||||||
194 | * |
||||||
195 | * @return false|null |
||||||
196 | */ |
||||||
197 | public function html_to_pdf( |
||||||
198 | $html_file_array, |
||||||
199 | $pdf_name = '', |
||||||
200 | $course_code = null, |
||||||
201 | $print_title = false, |
||||||
202 | $complete_style = true, |
||||||
203 | $addStyle = true, |
||||||
204 | $mainTitle = '', |
||||||
205 | $generateToFile = false |
||||||
206 | ) { |
||||||
207 | if (empty($html_file_array)) { |
||||||
208 | return false; |
||||||
209 | } |
||||||
210 | |||||||
211 | if (is_array($html_file_array)) { |
||||||
212 | if (count($html_file_array) == 0) { |
||||||
213 | return false; |
||||||
214 | } |
||||||
215 | } else { |
||||||
216 | if (!file_exists($html_file_array)) { |
||||||
217 | return false; |
||||||
218 | } |
||||||
219 | // Converting the string into an array |
||||||
220 | $html_file_array = [$html_file_array]; |
||||||
221 | } |
||||||
222 | |||||||
223 | if (!empty($course_code)) { |
||||||
224 | $course_data = api_get_course_info($course_code); |
||||||
225 | } else { |
||||||
226 | $course_data = api_get_course_info(); |
||||||
227 | } |
||||||
228 | |||||||
229 | // Clean styles and javascript document |
||||||
230 | $clean_search = [ |
||||||
231 | '@<script[^>]*?>.*?</script>@si', |
||||||
232 | '@<style[^>]*?>.*?</style>@si', |
||||||
233 | ]; |
||||||
234 | |||||||
235 | // Formatting the pdf |
||||||
236 | self::format_pdf($course_data, $complete_style); |
||||||
237 | |||||||
238 | $counter = 1; |
||||||
239 | foreach ($html_file_array as $file) { |
||||||
240 | // Add a page break per file |
||||||
241 | $page_break = '<pagebreak>'; |
||||||
242 | if ($counter == count($html_file_array)) { |
||||||
243 | $page_break = ''; |
||||||
244 | } |
||||||
245 | |||||||
246 | // if the array provided contained subarrays with 'title' entry, |
||||||
247 | // then print the title in the PDF |
||||||
248 | if (is_array($file) && isset($file['title'])) { |
||||||
249 | $html_title = $file['title']; |
||||||
250 | $file = $file['path']; |
||||||
251 | } else { |
||||||
252 | //we suppose we've only been sent a file path |
||||||
253 | $html_title = basename($file); |
||||||
254 | } |
||||||
255 | |||||||
256 | $counter++; |
||||||
257 | |||||||
258 | if (empty($file) && !empty($html_title)) { |
||||||
259 | // this is a chapter, print title & skip the rest |
||||||
260 | if ($counter === 2 && !empty($mainTitle)) { |
||||||
261 | $this->pdf->WriteHTML( |
||||||
262 | '<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>' |
||||||
263 | ); |
||||||
264 | } |
||||||
265 | if ($print_title) { |
||||||
266 | $this->pdf->WriteHTML( |
||||||
267 | '<html><body><h3>'.$html_title.'</h3></body></html>'.$page_break |
||||||
268 | ); |
||||||
269 | } |
||||||
270 | continue; |
||||||
271 | } else { |
||||||
272 | if ($counter === 2 && !empty($mainTitle)) { |
||||||
273 | $this->pdf->WriteHTML( |
||||||
274 | '<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>' |
||||||
275 | ); |
||||||
276 | } |
||||||
277 | } |
||||||
278 | |||||||
279 | if (!file_exists($file)) { |
||||||
280 | continue; |
||||||
281 | } |
||||||
282 | |||||||
283 | if ($addStyle) { |
||||||
284 | $basicStyles = [ |
||||||
285 | api_get_path(SYS_PATH).'web/assets/bootstrap/dist/css/bootstrap.min.css', |
||||||
286 | api_get_path(SYS_PATH).'web/css/base.css', |
||||||
287 | api_get_path(SYS_PATH).'web/css/themes/'.api_get_visual_theme().'/default.css', |
||||||
288 | api_get_print_css(false), |
||||||
289 | ]; |
||||||
290 | foreach ($basicStyles as $style) { |
||||||
291 | if (file_exists($style)) { |
||||||
292 | $cssContent = file_get_contents($style); |
||||||
293 | try { |
||||||
294 | @$this->pdf->WriteHTML($cssContent, 1); |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
WriteHTML() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
295 | } catch (MpdfException $e) { |
||||||
296 | error_log($e); |
||||||
297 | } |
||||||
298 | } |
||||||
299 | } |
||||||
300 | } |
||||||
301 | |||||||
302 | // it's not a chapter but the file exists, print its title |
||||||
303 | if ($print_title) { |
||||||
304 | @$this->pdf->WriteHTML( |
||||||
305 | '<html><body><h3>'.$html_title.'</h3></body></html>' |
||||||
306 | ); |
||||||
307 | } |
||||||
308 | |||||||
309 | $file_info = pathinfo($file); |
||||||
310 | $extension = $file_info['extension']; |
||||||
311 | |||||||
312 | if (in_array($extension, ['html', 'htm'])) { |
||||||
313 | $dirName = $file_info['dirname']; |
||||||
314 | $filename = $file_info['basename']; |
||||||
315 | $filename = str_replace('_', ' ', $filename); |
||||||
316 | |||||||
317 | if ($extension === 'html') { |
||||||
318 | $filename = basename($filename, '.html'); |
||||||
319 | } elseif ($extension === 'htm') { |
||||||
320 | $filename = basename($filename, '.htm'); |
||||||
321 | } |
||||||
322 | |||||||
323 | $document_html = @file_get_contents($file); |
||||||
324 | $document_html = preg_replace($clean_search, '', $document_html); |
||||||
325 | |||||||
326 | //absolute path for frames.css //TODO: necessary? |
||||||
327 | $absolute_css_path = api_get_path(WEB_CODE_PATH).'css/'.api_get_setting('stylesheets').'/frames.css'; |
||||||
328 | $document_html = str_replace('href="./css/frames.css"', $absolute_css_path, $document_html); |
||||||
329 | |||||||
330 | if (!empty($course_data['path'])) { |
||||||
331 | $document_html = str_replace('../', '', $document_html); |
||||||
332 | |||||||
333 | // Fix app/upload links convert web to system paths |
||||||
334 | $document_html = str_replace( |
||||||
335 | api_get_path(WEB_UPLOAD_PATH), |
||||||
336 | api_get_path(SYS_UPLOAD_PATH), |
||||||
337 | $document_html |
||||||
338 | ); |
||||||
339 | } |
||||||
340 | |||||||
341 | $document_html = self::fixImagesPaths($document_html, $course_data, $dirName); |
||||||
342 | |||||||
343 | // The library mPDF expects UTF-8 encoded input data. |
||||||
344 | api_set_encoding_html($document_html, 'UTF-8'); |
||||||
345 | // TODO: Maybe it is better idea the title to be passed through |
||||||
346 | $title = api_get_title_html($document_html, 'UTF-8', 'UTF-8'); |
||||||
347 | // $_GET[] too, as it is done with file name. |
||||||
348 | // At the moment the title is retrieved from the html document itself. |
||||||
349 | if (empty($title)) { |
||||||
350 | $title = $filename; // Here file name is expected to contain ASCII symbols only. |
||||||
351 | } |
||||||
352 | if (!empty($document_html)) { |
||||||
353 | @$this->pdf->WriteHTML($document_html.$page_break); |
||||||
354 | } |
||||||
355 | } elseif (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) { |
||||||
356 | // Images |
||||||
357 | $image = Display::img($file); |
||||||
358 | @$this->pdf->WriteHTML('<html><body>'.$image.'</body></html>'.$page_break); |
||||||
359 | } |
||||||
360 | } |
||||||
361 | if (empty($pdf_name)) { |
||||||
362 | $output_file = 'pdf_'.date('Y-m-d-his').'.pdf'; |
||||||
363 | } else { |
||||||
364 | $pdf_name = api_replace_dangerous_char($pdf_name); |
||||||
365 | $output_file = $pdf_name.'.pdf'; |
||||||
366 | } |
||||||
367 | // F to save the pdf in a file |
||||||
368 | if ($generateToFile) { |
||||||
369 | @$this->pdf->Output( |
||||||
370 | api_get_path(SYS_ARCHIVE_PATH).$output_file, |
||||||
371 | 'F' |
||||||
372 | ); |
||||||
373 | } else { |
||||||
374 | @$this->pdf->Output($output_file, 'D'); |
||||||
375 | } |
||||||
376 | |||||||
377 | exit; |
||||||
0 ignored issues
–
show
|
|||||||
378 | } |
||||||
379 | |||||||
380 | /** |
||||||
381 | * Converts an html string to PDF. |
||||||
382 | * |
||||||
383 | * @param string $document_html valid html |
||||||
384 | * @param string $css CSS content of a CSS file |
||||||
385 | * @param string $pdf_name pdf name |
||||||
386 | * @param string $course_code course code |
||||||
387 | * (if you are using html that are located in the document tool you must provide this) |
||||||
388 | * @param string $outputMode the MPDF output mode can be: |
||||||
389 | * @param bool $saveInFile |
||||||
390 | * @param string $fileToSave |
||||||
391 | * @param bool $returnHtml |
||||||
392 | * @param bool $addDefaultCss |
||||||
393 | * @param bool $completeHeader |
||||||
394 | * |
||||||
395 | * 'I' (print on standard output), |
||||||
396 | * 'D' (download file) (this is the default value), |
||||||
397 | * 'F' (save to local file) or |
||||||
398 | * 'S' (return as a string) |
||||||
399 | * |
||||||
400 | * @throws MpdfException |
||||||
401 | * |
||||||
402 | * @return string Web path |
||||||
403 | */ |
||||||
404 | public function content_to_pdf( |
||||||
405 | $document_html, |
||||||
406 | $css = '', |
||||||
407 | $pdf_name = '', |
||||||
408 | $course_code = null, |
||||||
409 | $outputMode = 'D', |
||||||
410 | $saveInFile = false, |
||||||
411 | $fileToSave = null, |
||||||
412 | $returnHtml = false, |
||||||
413 | $addDefaultCss = false, |
||||||
414 | $completeHeader = true |
||||||
415 | ) { |
||||||
416 | $urlAppend = api_get_configuration_value('url_append'); |
||||||
417 | |||||||
418 | if (empty($document_html)) { |
||||||
419 | return false; |
||||||
420 | } |
||||||
421 | |||||||
422 | // clean styles and javascript document |
||||||
423 | $clean_search = [ |
||||||
424 | '@<script[^>]*?>.*?</script>@si', |
||||||
425 | '@<style[^>]*?>.*?</style>@siU', |
||||||
426 | ]; |
||||||
427 | |||||||
428 | // Formatting the pdf |
||||||
429 | $course_data = api_get_course_info($course_code); |
||||||
430 | self::format_pdf($course_data, $completeHeader); |
||||||
0 ignored issues
–
show
The method
PDF::format_pdf() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
431 | $document_html = preg_replace($clean_search, '', $document_html); |
||||||
432 | |||||||
433 | //absolute path for frames.css //TODO: necessary? |
||||||
434 | $absolute_css_path = api_get_path(WEB_CSS_PATH).api_get_setting('stylesheets').'/frames.css'; |
||||||
435 | $document_html = str_replace('href="./css/frames.css"', 'href="'.$absolute_css_path.'"', $document_html); |
||||||
436 | $document_html = str_replace('../../', '', $document_html); |
||||||
437 | $document_html = str_replace('../', '', $document_html); |
||||||
438 | $document_html = str_replace( |
||||||
439 | (empty($urlAppend) ? '' : $urlAppend.'/').'courses/'.$course_code.'/document/', |
||||||
440 | '', |
||||||
441 | $document_html |
||||||
442 | ); |
||||||
443 | |||||||
444 | if (!empty($course_data['path'])) { |
||||||
445 | $document_path = api_get_path(SYS_COURSE_PATH).$course_data['path'].'/document/'; |
||||||
446 | |||||||
447 | $doc = new DOMDocument(); |
||||||
448 | @$doc->loadHTML($document_html); |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
loadHTML() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
449 | |||||||
450 | //Fixing only images @todo do the same thing with other elements |
||||||
451 | $elements = $doc->getElementsByTagName('img'); |
||||||
452 | $protocol = api_get_protocol(); |
||||||
453 | $replaced = []; |
||||||
454 | if (!empty($elements)) { |
||||||
455 | foreach ($elements as $item) { |
||||||
456 | $old_src = $item->getAttribute('src'); |
||||||
457 | |||||||
458 | if (in_array($old_src, $replaced)) { |
||||||
459 | continue; |
||||||
460 | } |
||||||
461 | |||||||
462 | if (strpos($old_src, $protocol) === false) { |
||||||
463 | if (strpos($old_src, '/main/default_course_document') === false) { |
||||||
464 | if (strpos($old_src, '/main/inc/lib/') === false && |
||||||
465 | strpos($old_src, '/app/upload/') === false |
||||||
466 | ) { |
||||||
467 | $old_src_fixed = str_replace( |
||||||
468 | api_get_path(REL_COURSE_PATH).$course_data['path'].'/document/', |
||||||
469 | '', |
||||||
470 | $old_src |
||||||
471 | ); |
||||||
472 | $old_src_fixed = str_replace( |
||||||
473 | 'courses/'.$course_data['path'].'/document/', |
||||||
474 | '', |
||||||
475 | $old_src_fixed |
||||||
476 | ); |
||||||
477 | $new_path = $document_path.$old_src_fixed; |
||||||
478 | $document_html = str_replace($old_src, $new_path, $document_html); |
||||||
479 | $replaced[] = $old_src; |
||||||
480 | } |
||||||
481 | } |
||||||
482 | } |
||||||
483 | } |
||||||
484 | } |
||||||
485 | } |
||||||
486 | |||||||
487 | // Use sys path to correct export images |
||||||
488 | $document_html = str_replace( |
||||||
489 | api_get_path(WEB_CODE_PATH).'img/', |
||||||
490 | api_get_path(SYS_CODE_PATH).'img/', |
||||||
491 | $document_html |
||||||
492 | ); |
||||||
493 | |||||||
494 | $theme = api_get_visual_theme(); |
||||||
495 | $document_html = str_replace( |
||||||
496 | api_get_path(WEB_CSS_PATH).'themes/'.$theme, |
||||||
497 | api_get_path(SYS_PUBLIC_PATH).'css/themes/'.$theme, |
||||||
498 | $document_html |
||||||
499 | ); |
||||||
500 | |||||||
501 | $document_html = str_replace(api_get_path(WEB_UPLOAD_PATH), api_get_path(SYS_UPLOAD_PATH), $document_html); |
||||||
502 | $document_html = str_replace(api_get_path(WEB_ARCHIVE_PATH), api_get_path(SYS_ARCHIVE_PATH), $document_html); |
||||||
503 | |||||||
504 | // The library mPDF expects UTF-8 encoded input data. |
||||||
505 | api_set_encoding_html($document_html, 'UTF-8'); |
||||||
506 | // At the moment the title is retrieved from the html document itself. |
||||||
507 | if ($returnHtml) { |
||||||
508 | return "<style>$css</style>".$document_html; |
||||||
509 | } |
||||||
510 | |||||||
511 | if (!empty($css)) { |
||||||
512 | try { |
||||||
513 | @$this->pdf->WriteHTML($css, 1); |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
WriteHTML() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
514 | } catch (MpdfException $e) { |
||||||
515 | error_log($e); |
||||||
516 | } |
||||||
517 | } |
||||||
518 | |||||||
519 | $cssBootstrap = file_get_contents(api_get_path(SYS_PATH).'web/assets/bootstrap/dist/css/bootstrap.min.css'); |
||||||
520 | if ($addDefaultCss) { |
||||||
521 | $cssContent = api_get_print_css(); |
||||||
522 | try { |
||||||
523 | @$this->pdf->WriteHTML($cssBootstrap, 1); |
||||||
524 | @$this->pdf->WriteHTML($cssContent, 1); |
||||||
525 | } catch (MpdfException $e) { |
||||||
526 | error_log($e); |
||||||
527 | } |
||||||
528 | } |
||||||
529 | |||||||
530 | try { |
||||||
531 | @$this->pdf->WriteHTML($document_html); |
||||||
532 | } catch (MpdfException $e) { |
||||||
533 | error_log($e); |
||||||
534 | } |
||||||
535 | |||||||
536 | if (empty($pdf_name)) { |
||||||
537 | $output_file = 'pdf_'.date('Y-m-d-his').'.pdf'; |
||||||
538 | } else { |
||||||
539 | $pdf_name = api_replace_dangerous_char($pdf_name); |
||||||
540 | $output_file = $pdf_name.'.pdf'; |
||||||
541 | } |
||||||
542 | |||||||
543 | if ($outputMode === 'F') { |
||||||
544 | $output_file = api_get_path(SYS_ARCHIVE_PATH).$output_file; |
||||||
545 | } |
||||||
546 | |||||||
547 | if ($saveInFile) { |
||||||
548 | $fileToSave = !empty($fileToSave) ? $fileToSave : api_get_path(SYS_ARCHIVE_PATH).uniqid(); |
||||||
549 | @$this->pdf->Output( |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
Output() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
550 | $fileToSave, |
||||||
551 | $outputMode |
||||||
552 | ); // F to save the pdf in a file |
||||||
553 | } else { |
||||||
554 | @$this->pdf->Output( |
||||||
555 | $output_file, |
||||||
556 | $outputMode |
||||||
557 | ); // F to save the pdf in a file |
||||||
558 | } |
||||||
559 | |||||||
560 | if ($outputMode != 'F') { |
||||||
561 | exit; |
||||||
562 | } |
||||||
563 | |||||||
564 | return $output_file; |
||||||
565 | } |
||||||
566 | |||||||
567 | /** |
||||||
568 | * Gets the watermark from the platform or a course. |
||||||
569 | * |
||||||
570 | * @param string course code (optional) |
||||||
571 | * @param mixed web path of the watermark image, false if there is nothing to return |
||||||
572 | * |
||||||
573 | * @return string |
||||||
574 | */ |
||||||
575 | public static function get_watermark($course_code = null) |
||||||
576 | { |
||||||
577 | $web_path = false; |
||||||
578 | $urlId = api_get_current_access_url_id(); |
||||||
579 | if (!empty($course_code) && api_get_setting('pdf_export_watermark_by_course') === 'true') { |
||||||
580 | $course_info = api_get_course_info($course_code); |
||||||
581 | // course path |
||||||
582 | $store_path = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/'.$urlId.'_pdf_watermark.png'; |
||||||
583 | if (file_exists($store_path)) { |
||||||
584 | $web_path = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/'.$urlId.'_pdf_watermark.png'; |
||||||
585 | } |
||||||
586 | } else { |
||||||
587 | // course path |
||||||
588 | $store_path = api_get_path(SYS_CODE_PATH).'default_course_document/images/'.$urlId.'_pdf_watermark.png'; |
||||||
589 | if (file_exists($store_path)) { |
||||||
590 | $web_path = api_get_path(WEB_CODE_PATH).'default_course_document/images/'.$urlId.'_pdf_watermark.png'; |
||||||
591 | } |
||||||
592 | } |
||||||
593 | |||||||
594 | return $web_path; |
||||||
0 ignored issues
–
show
The expression
return $web_path could also return false which is incompatible with the documented return type string . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.
Loading history...
|
|||||||
595 | } |
||||||
596 | |||||||
597 | /** |
||||||
598 | * Deletes the watermark from the Platform or Course. |
||||||
599 | * |
||||||
600 | * @param string $course_code course code (optional) |
||||||
601 | * @param mixed web path of the watermark image, false if there is nothing to return |
||||||
602 | * |
||||||
603 | * @return bool |
||||||
604 | */ |
||||||
605 | public function delete_watermark($course_code = null) |
||||||
606 | { |
||||||
607 | $urlId = api_get_current_access_url_id(); |
||||||
608 | if (!empty($course_code) && api_get_setting('pdf_export_watermark_by_course') == 'true') { |
||||||
609 | $course_info = api_get_course_info($course_code); |
||||||
610 | // course path |
||||||
611 | $store_path = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/'.$urlId.'_pdf_watermark.png'; |
||||||
612 | } else { |
||||||
613 | // course path |
||||||
614 | $store_path = api_get_path(SYS_CODE_PATH).'default_course_document/images/'.$urlId.'_pdf_watermark.png'; |
||||||
615 | } |
||||||
616 | if (file_exists($store_path)) { |
||||||
617 | unlink($store_path); |
||||||
618 | |||||||
619 | return true; |
||||||
620 | } |
||||||
621 | |||||||
622 | return false; |
||||||
623 | } |
||||||
624 | |||||||
625 | /** |
||||||
626 | * Uploads the pdf watermark in the main/default_course_document directory or in the course directory. |
||||||
627 | * |
||||||
628 | * @param string $filename filename |
||||||
629 | * @param string $source_file path of the file |
||||||
630 | * @param string $course_code |
||||||
631 | * |
||||||
632 | * @return mixed web path of the file if sucess, false otherwise |
||||||
633 | */ |
||||||
634 | public function upload_watermark($filename, $source_file, $course_code = null) |
||||||
635 | { |
||||||
636 | $urlId = api_get_current_access_url_id(); |
||||||
637 | if (!empty($course_code) && api_get_setting('pdf_export_watermark_by_course') == 'true') { |
||||||
638 | $course_info = api_get_course_info($course_code); |
||||||
639 | $store_path = api_get_path(SYS_COURSE_PATH).$course_info['path']; // course path |
||||||
640 | $web_path = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/pdf_watermark.png'; |
||||||
641 | } else { |
||||||
642 | $store_path = api_get_path(SYS_CODE_PATH).'default_course_document/images'; // course path |
||||||
643 | $web_path = api_get_path(WEB_CODE_PATH).'default_course_document/images/'.$urlId.'_pdf_watermark.png'; |
||||||
644 | } |
||||||
645 | $course_image = $store_path.'/'.$urlId.'_pdf_watermark.png'; |
||||||
646 | |||||||
647 | if (file_exists($course_image)) { |
||||||
648 | @unlink($course_image); |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
649 | } |
||||||
650 | $my_image = new Image($source_file); |
||||||
651 | $result = $my_image->send_image($course_image, -1, 'png'); |
||||||
652 | if ($result) { |
||||||
653 | $result = $web_path; |
||||||
654 | } |
||||||
655 | |||||||
656 | return $result; |
||||||
657 | } |
||||||
658 | |||||||
659 | /** |
||||||
660 | * Returns the default header. |
||||||
661 | */ |
||||||
662 | public function get_header($course_code = null) |
||||||
663 | { |
||||||
664 | /*$header = api_get_setting('pdf_export_watermark_text'); |
||||||
665 | if (!empty($course_code) && api_get_setting('pdf_export_watermark_by_course') == 'true') { |
||||||
666 | $header = api_get_course_setting('pdf_export_watermark_text'); |
||||||
667 | } |
||||||
668 | return $header;*/ |
||||||
669 | } |
||||||
670 | |||||||
671 | /** |
||||||
672 | * Sets the PDF footer. |
||||||
673 | */ |
||||||
674 | public function set_footer() |
||||||
675 | { |
||||||
676 | $this->pdf->defaultfooterfontsize = 12; // in pts |
||||||
677 | $this->pdf->defaultfooterfontstyle = 'B'; // blank, B, I, or BI |
||||||
678 | $this->pdf->defaultfooterline = 1; // 1 to include line below header/above footer |
||||||
679 | |||||||
680 | $view = new Template('', false, false, false, true, false, false); |
||||||
681 | $template = $view->get_template('export/pdf_footer.tpl'); |
||||||
682 | $footerHTML = $view->fetch($template); |
||||||
683 | |||||||
684 | $this->pdf->SetHTMLFooter($footerHTML, 'E'); //Even pages |
||||||
685 | $this->pdf->SetHTMLFooter($footerHTML, 'O'); //Odd pages |
||||||
686 | } |
||||||
687 | |||||||
688 | public function setCertificateFooter() |
||||||
689 | { |
||||||
690 | $this->pdf->defaultfooterfontsize = 12; // in pts |
||||||
691 | $this->pdf->defaultfooterfontstyle = 'B'; // blank, B, I, or BI |
||||||
692 | $this->pdf->defaultfooterline = 1; // 1 to include line below header/above footer |
||||||
693 | |||||||
694 | $view = new Template('', false, false, false, true, false, false); |
||||||
695 | $template = $view->get_template('export/pdf_certificate_footer.tpl'); |
||||||
696 | $footerHTML = $view->fetch($template); |
||||||
697 | |||||||
698 | $this->pdf->SetHTMLFooter($footerHTML, 'E'); //Even pages |
||||||
699 | $this->pdf->SetHTMLFooter($footerHTML, 'O'); //Odd pages |
||||||
700 | } |
||||||
701 | |||||||
702 | /** |
||||||
703 | * Sets the PDF header. |
||||||
704 | * |
||||||
705 | * @param array $courseInfo |
||||||
706 | */ |
||||||
707 | public function set_header($courseInfo) |
||||||
708 | { |
||||||
709 | $this->pdf->defaultheaderfontsize = 10; // in pts |
||||||
710 | $this->pdf->defaultheaderfontstyle = 'BI'; // blank, B, I, or BI |
||||||
711 | $this->pdf->defaultheaderline = 1; // 1 to include line below header/above footer |
||||||
712 | |||||||
713 | $userId = api_get_user_id(); |
||||||
714 | if (!empty($courseInfo['code'])) { |
||||||
715 | $teacher_list = CourseManager::get_teacher_list_from_course_code($courseInfo['code']); |
||||||
716 | |||||||
717 | $teachers = ''; |
||||||
718 | if (!empty($teacher_list)) { |
||||||
719 | foreach ($teacher_list as $teacher) { |
||||||
720 | if ($teacher['user_id'] != $userId) { |
||||||
721 | continue; |
||||||
722 | } |
||||||
723 | |||||||
724 | // Do not show the teacher list see BT#4080 only the current teacher name |
||||||
725 | $teachers = api_get_person_name($teacher['firstname'], $teacher['lastname']); |
||||||
726 | } |
||||||
727 | } |
||||||
728 | |||||||
729 | $organization = ChamiloApi::getPlatformLogo('', [], true, true); |
||||||
730 | // Use custom logo image. |
||||||
731 | $pdfLogo = api_get_setting('pdf_logo_header'); |
||||||
732 | if ($pdfLogo === 'true') { |
||||||
733 | $visualTheme = api_get_visual_theme(); |
||||||
734 | $img = api_get_path(SYS_CSS_PATH).'themes/'.$visualTheme.'/images/pdf_logo_header.png'; |
||||||
735 | if (file_exists($img)) { |
||||||
736 | $organization = "<img src='$img'>"; |
||||||
737 | } |
||||||
738 | } |
||||||
739 | |||||||
740 | $view = new Template('', false, false, false, true, false, false); |
||||||
741 | $view->assign('teacher_name', $teachers); |
||||||
742 | $view->assign('organization', $organization); |
||||||
743 | $template = $view->get_template('export/pdf_header.tpl'); |
||||||
744 | $headerHTML = $view->fetch($template); |
||||||
745 | |||||||
746 | $this->pdf->SetHTMLHeader($headerHTML, 'E'); |
||||||
747 | $this->pdf->SetHTMLHeader($headerHTML, 'O'); |
||||||
748 | } |
||||||
749 | } |
||||||
750 | |||||||
751 | /** |
||||||
752 | * @param string $header html content |
||||||
753 | */ |
||||||
754 | public function set_custom_header($header) |
||||||
755 | { |
||||||
756 | $this->custom_header = $header; |
||||||
757 | } |
||||||
758 | |||||||
759 | /** |
||||||
760 | * @param array $footer html content |
||||||
761 | */ |
||||||
762 | public function set_custom_footer($footer) |
||||||
763 | { |
||||||
764 | $this->custom_footer = $footer; |
||||||
765 | } |
||||||
766 | |||||||
767 | /** |
||||||
768 | * Pre-formats a PDF to the right size and, if not stated otherwise, with |
||||||
769 | * header, footer and watermark (if any). |
||||||
770 | * |
||||||
771 | * @param array $courseInfo General course information (to fill headers) |
||||||
772 | * @param bool $complete Whether we want headers, footers and watermark or not |
||||||
773 | */ |
||||||
774 | public function format_pdf($courseInfo, $complete = true) |
||||||
775 | { |
||||||
776 | $courseCode = null; |
||||||
777 | if (!empty($courseInfo)) { |
||||||
778 | $courseCode = $courseInfo['code']; |
||||||
779 | } |
||||||
780 | |||||||
781 | /*$pdf->SetAuthor('Documents Chamilo'); |
||||||
782 | $pdf->SetTitle('title'); |
||||||
783 | $pdf->SetSubject('Exported from Chamilo Documents'); |
||||||
784 | $pdf->SetKeywords('Chamilo Documents'); |
||||||
785 | */ |
||||||
786 | // TODO: To be read from the html document. |
||||||
787 | $this->pdf->directionality = api_get_text_direction(); |
||||||
788 | $this->pdf->useOnlyCoreFonts = true; |
||||||
789 | // Use different Odd/Even headers and footers and mirror margins |
||||||
790 | $this->pdf->mirrorMargins = 1; |
||||||
791 | |||||||
792 | // Add decoration only if not stated otherwise |
||||||
793 | if ($complete) { |
||||||
794 | // Adding watermark |
||||||
795 | if (api_get_setting('pdf_export_watermark_enable') === 'true') { |
||||||
796 | $watermark_file = self::get_watermark($courseCode); |
||||||
797 | if ($watermark_file) { |
||||||
798 | //http://mpdf1.com/manual/index.php?tid=269&searchstring=watermark |
||||||
799 | $this->pdf->SetWatermarkImage($watermark_file); |
||||||
800 | $this->pdf->showWatermarkImage = true; |
||||||
801 | } else { |
||||||
802 | $watermark_file = self::get_watermark(null); |
||||||
803 | |||||||
804 | if ($watermark_file) { |
||||||
805 | $this->pdf->SetWatermarkImage($watermark_file); |
||||||
806 | $this->pdf->showWatermarkImage = true; |
||||||
807 | } |
||||||
808 | } |
||||||
809 | |||||||
810 | $watermark_text = api_get_setting('pdf_export_watermark_text'); |
||||||
811 | if ($courseCode && 'true' === api_get_setting('pdf_export_watermark_by_course')) { |
||||||
812 | $courseWaterMark = api_get_course_setting('pdf_export_watermark_text'); |
||||||
813 | if (!empty($courseWaterMark) && -1 != $courseWaterMark) { |
||||||
814 | $watermark_text = $courseWaterMark; |
||||||
815 | } |
||||||
816 | } |
||||||
817 | |||||||
818 | if (!empty($watermark_text)) { |
||||||
819 | $this->pdf->SetWatermarkText( |
||||||
820 | strcode2utf($watermark_text), |
||||||
0 ignored issues
–
show
The function
strcode2utf was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
821 | 0.1 |
||||||
822 | ); |
||||||
823 | $this->pdf->showWatermarkText = true; |
||||||
824 | } |
||||||
825 | } |
||||||
826 | |||||||
827 | if (empty($this->custom_header)) { |
||||||
828 | self::set_header($courseInfo); |
||||||
0 ignored issues
–
show
The method
PDF::set_header() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
829 | } else { |
||||||
830 | $this->pdf->SetHTMLHeader($this->custom_header, 'E'); |
||||||
831 | $this->pdf->SetHTMLHeader($this->custom_header, 'O'); |
||||||
832 | } |
||||||
833 | |||||||
834 | if (empty($this->custom_footer)) { |
||||||
835 | self::set_footer(); |
||||||
0 ignored issues
–
show
The method
PDF::set_footer() is not static, but was called statically.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
836 | } else { |
||||||
837 | $this->pdf->SetHTMLFooter($this->custom_footer); |
||||||
838 | } |
||||||
839 | } |
||||||
840 | } |
||||||
841 | |||||||
842 | /** |
||||||
843 | * Generate a PDF file from $html in SYS_APP_PATH. |
||||||
844 | * |
||||||
845 | * @param string $html PDF content |
||||||
846 | * @param string $fileName File name |
||||||
847 | * @param string $dest Optional. Directory to move file |
||||||
848 | * |
||||||
849 | * @return string The PDF path |
||||||
850 | */ |
||||||
851 | public function exportFromHtmlToFile($html, $fileName, $dest = null) |
||||||
852 | { |
||||||
853 | $this->template = $this->template ?: new Template('', false, false, false, false, false, false); |
||||||
854 | |||||||
855 | $pdfPath = self::content_to_pdf( |
||||||
856 | $html, |
||||||
857 | api_get_print_css(), |
||||||
858 | $fileName, |
||||||
859 | $this->params['course_code'], |
||||||
860 | 'F' |
||||||
861 | ); |
||||||
862 | |||||||
863 | if (!$dest) { |
||||||
864 | return $pdfPath; |
||||||
865 | } |
||||||
866 | |||||||
867 | move($pdfPath, $dest); |
||||||
868 | |||||||
869 | return $dest.basename($pdfPath); |
||||||
870 | } |
||||||
871 | |||||||
872 | /** |
||||||
873 | * Create a PDF and save it into the documents area. |
||||||
874 | * |
||||||
875 | * @param string $htmlContent HTML Content |
||||||
876 | * @param string $fileName The file name |
||||||
877 | * @param int $courseId The course ID |
||||||
878 | * @param int $sessionId Optional. The session ID |
||||||
879 | */ |
||||||
880 | public function exportFromHtmlToDocumentsArea( |
||||||
881 | $htmlContent, |
||||||
882 | $fileName, |
||||||
883 | $courseId, |
||||||
884 | $sessionId = 0 |
||||||
885 | ) { |
||||||
886 | $userId = api_get_user_id(); |
||||||
887 | $courseInfo = api_get_course_info_by_id($courseId); |
||||||
888 | $courseDirectory = api_get_path(SYS_COURSE_PATH).$courseInfo['directory'].'/document/'; |
||||||
889 | |||||||
890 | $docPath = $this->exportFromHtmlToFile( |
||||||
891 | $htmlContent, |
||||||
892 | $fileName, |
||||||
893 | $courseDirectory |
||||||
894 | ); |
||||||
895 | |||||||
896 | $docId = add_document( |
||||||
897 | $courseInfo, |
||||||
898 | str_replace($courseDirectory, '/', $docPath), |
||||||
899 | 'file', |
||||||
900 | filesize($docPath), |
||||||
901 | $fileName, |
||||||
902 | null, |
||||||
903 | false, |
||||||
904 | true, |
||||||
905 | null, |
||||||
906 | $sessionId, |
||||||
907 | $userId |
||||||
908 | ); |
||||||
909 | |||||||
910 | api_item_property_update( |
||||||
911 | $courseInfo, |
||||||
912 | TOOL_DOCUMENT, |
||||||
913 | $docId, |
||||||
914 | 'DocumentAdded', |
||||||
915 | $userId |
||||||
916 | ); |
||||||
917 | |||||||
918 | Display::addFlash(Display::return_message(get_lang('ItemAdded'))); |
||||||
919 | } |
||||||
920 | |||||||
921 | /** |
||||||
922 | * @param string $theme |
||||||
923 | * @param bool $fullPage |
||||||
924 | * |
||||||
925 | * @throws MpdfException |
||||||
926 | */ |
||||||
927 | public function setBackground($theme, $fullPage = false) |
||||||
928 | { |
||||||
929 | $themeName = empty($theme) ? api_get_visual_theme() : $theme; |
||||||
930 | $themeDir = \Template::getThemeDir($themeName); |
||||||
931 | $customLetterhead = $themeDir.'images/letterhead.png'; |
||||||
932 | $urlPathLetterhead = api_get_path(SYS_CSS_PATH).$customLetterhead; |
||||||
933 | |||||||
934 | if (file_exists($urlPathLetterhead)) { |
||||||
935 | $urlWebLetterhead = 'url('.api_get_path(WEB_CSS_PATH).$customLetterhead.')'; |
||||||
936 | } else { |
||||||
937 | $urlWebLetterhead = 'url('.api_get_path(WEB_CSS_PATH).'themes/chamilo/images/letterhead.png)'; |
||||||
938 | } |
||||||
939 | |||||||
940 | if ($fullPage) { |
||||||
941 | $this->pdf->SetDisplayMode('fullpage'); |
||||||
942 | $this->pdf->SetDefaultBodyCSS('background', $urlWebLetterhead); |
||||||
943 | $this->pdf->SetDefaultBodyCSS('background-image-resize', '6'); |
||||||
944 | } |
||||||
945 | } |
||||||
946 | |||||||
947 | /** |
||||||
948 | * Fix images source paths to allow export to pdf. |
||||||
949 | * |
||||||
950 | * @param string $documentHtml |
||||||
951 | * @param string $dirName |
||||||
952 | * |
||||||
953 | * @return string |
||||||
954 | */ |
||||||
955 | private static function fixImagesPaths($documentHtml, array $courseInfo, $dirName = '') |
||||||
956 | { |
||||||
957 | $documentHtml = '<?xml encoding="utf-8" ?>'.$documentHtml; |
||||||
958 | $doc = new DOMDocument(); |
||||||
959 | @$doc->loadHTML($documentHtml); |
||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
loadHTML() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||||
960 | |||||||
961 | $elements = $doc->getElementsByTagName('img'); |
||||||
962 | |||||||
963 | if (empty($elements)) { |
||||||
964 | return $doc->saveHTML(); |
||||||
965 | } |
||||||
966 | |||||||
967 | $protocol = api_get_protocol(); |
||||||
968 | $sysCodePath = api_get_path(SYS_CODE_PATH); |
||||||
969 | $sysCoursePath = api_get_path(SYS_COURSE_PATH); |
||||||
970 | $sysUploadPath = api_get_path(SYS_UPLOAD_PATH); |
||||||
971 | |||||||
972 | $documentPath = $courseInfo ? $sysCoursePath.$courseInfo['path'].'/document/' : ''; |
||||||
973 | |||||||
974 | /** @var \DOMElement $element */ |
||||||
975 | foreach ($elements as $element) { |
||||||
976 | $src = $element->getAttribute('src'); |
||||||
977 | $src = trim($src); |
||||||
978 | |||||||
979 | if (strpos($src, $protocol) !== false) { |
||||||
980 | continue; |
||||||
981 | } |
||||||
982 | |||||||
983 | // It's a reference to a file in the system, do not change it |
||||||
984 | if (file_exists($src)) { |
||||||
985 | continue; |
||||||
986 | } |
||||||
987 | |||||||
988 | if (strpos($src, '/main/default_course_document') === 0) { |
||||||
989 | $element->setAttribute( |
||||||
990 | 'src', |
||||||
991 | str_replace('/main/default_course_document', $sysCodePath.'default_course_document', $src) |
||||||
992 | ); |
||||||
993 | continue; |
||||||
994 | } |
||||||
995 | |||||||
996 | if (strpos($src, '/main/img') === 0) { |
||||||
997 | $element->setAttribute( |
||||||
998 | 'src', |
||||||
999 | str_replace('/main/img/', $sysCodePath.'img/', $src) |
||||||
1000 | ); |
||||||
1001 | continue; |
||||||
1002 | } |
||||||
1003 | |||||||
1004 | if (strpos($src, '/app/upload/') === 0) { |
||||||
1005 | $element->setAttribute( |
||||||
1006 | 'src', |
||||||
1007 | str_replace('/app/upload/', $sysUploadPath, $src) |
||||||
1008 | ); |
||||||
1009 | continue; |
||||||
1010 | } |
||||||
1011 | |||||||
1012 | if (empty($courseInfo)) { |
||||||
1013 | continue; |
||||||
1014 | } |
||||||
1015 | |||||||
1016 | if (api_get_path(REL_PATH) != '/') { |
||||||
1017 | $oldSrcFixed = str_replace( |
||||||
1018 | api_get_path(REL_PATH).'courses/'.$courseInfo['path'].'/document/', |
||||||
1019 | '', |
||||||
1020 | $src |
||||||
1021 | ); |
||||||
1022 | |||||||
1023 | // Try with the dirname if exists |
||||||
1024 | if ($oldSrcFixed == $src) { |
||||||
1025 | if (file_exists($dirName.'/'.$src)) { |
||||||
1026 | $documentPath = ''; |
||||||
1027 | $oldSrcFixed = $dirName.'/'.$src; |
||||||
1028 | } |
||||||
1029 | } |
||||||
1030 | } else { |
||||||
1031 | if (strpos($src, 'courses/'.$courseInfo['path'].'/document/') !== false) { |
||||||
1032 | $oldSrcFixed = str_replace('courses/'.$courseInfo['path'].'/document/', '', $src); |
||||||
1033 | } else { |
||||||
1034 | // Try with the dirname if exists |
||||||
1035 | if (file_exists($dirName.'/'.$src)) { |
||||||
1036 | $documentPath = ''; |
||||||
1037 | $oldSrcFixed = $dirName.'/'.$src; |
||||||
1038 | } else { |
||||||
1039 | $documentPath = ''; |
||||||
1040 | $oldSrcFixed = $src; |
||||||
1041 | } |
||||||
1042 | } |
||||||
1043 | } |
||||||
1044 | |||||||
1045 | $element->setAttribute('src', $documentPath.$oldSrcFixed); |
||||||
1046 | } |
||||||
1047 | |||||||
1048 | return $doc->saveHTML(); |
||||||
1049 | } |
||||||
1050 | } |
||||||
1051 |