1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4require_once './Services/PDFGeneration/classes/factory/class.ilHtmlToPdfTransformerFactory.php'; 5require_once './Services/PDFGeneration/classes/class.ilPDFGeneratorUtils.php'; 6 7/** 8 * Class ilTestPDFGenerator 9 * 10 * Class that handles PDF generation for test and assessment. 11 * 12 * @author Maximilian Becker <mbecker@databay.de> 13 * @version $Id$ 14 * 15 */ 16class ilTestPDFGenerator 17{ 18 const PDF_OUTPUT_DOWNLOAD = 'D'; 19 const PDF_OUTPUT_INLINE = 'I'; 20 const PDF_OUTPUT_FILE = 'F'; 21 22 const service = "Test"; 23 24 private static function buildHtmlDocument($contentHtml, $styleHtml) 25 { 26 return " 27 <html> 28 <head> 29 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> 30 $styleHtml 31 </head> 32 <body>$contentHtml</body> 33 </html> 34 "; 35 } 36 37 /** 38 * @param $html 39 * @return string 40 */ 41 private static function makeHtmlDocument($contentHtml, $styleHtml) 42 { 43 if (!is_string($contentHtml) || !strlen(trim($contentHtml))) { 44 return $contentHtml; 45 } 46 47 $html = self::buildHtmlDocument($contentHtml, $styleHtml); 48 49 $dom = new DOMDocument("1.0", "utf-8"); 50 if (!@$dom->loadHTML($html)) { 51 return $html; 52 } 53 54 $invalid_elements = array(); 55 56 $script_elements = $dom->getElementsByTagName('script'); 57 foreach ($script_elements as $elm) { 58 $invalid_elements[] = $elm; 59 } 60 61 foreach ($invalid_elements as $elm) { 62 $elm->parentNode->removeChild($elm); 63 } 64 65 // remove noprint elems as tcpdf will make empty pdf when hidden by css rules 66 $domX = new DomXPath($dom); 67 foreach ($domX->query("//*[contains(@class, 'noprint')]") as $node) { 68 $node->parentNode->removeChild($node); 69 } 70 71 $dom->encoding = 'UTF-8'; 72 73 $img_src_map = array(); 74 foreach ($dom->getElementsByTagName('img') as $elm) { 75 /** @var $elm DOMElement $uid */ 76 $uid = 'img_src_' . uniqid(); 77 $src = $elm->getAttribute('src'); 78 79 $elm->setAttribute('src', $uid); 80 81 $img_src_map[$uid] = $src; 82 } 83 84 $cleaned_html = $dom->saveHTML(); 85 86 foreach ($img_src_map as $uid => $src) { 87 $cleaned_html = str_replace($uid, $src, $cleaned_html); 88 } 89 90 if (!$cleaned_html) { 91 return $html; 92 } 93 94 return $cleaned_html; 95 } 96 97 public static function generatePDF($pdf_output, $output_mode, $filename = null, $purpose = null) 98 { 99 $pdf_output = self::preprocessHTML($pdf_output); 100 101 if (substr($filename, strlen($filename) - 4, 4) != '.pdf') { 102 $filename .= '.pdf'; 103 } 104 $pdf_factory = new ilHtmlToPdfTransformerFactory(); 105 return $pdf_factory->deliverPDFFromHTMLString($pdf_output, $filename, $output_mode, self::service, $purpose); 106 } 107 108 public static function preprocessHTML($html) 109 { 110 $html = self::makeHtmlDocument($html, '<style>' . self::getCssContent() . '</style>'); 111 112 return $html; 113 } 114 115 protected static function getTemplatePath($a_filename, $module_path = 'Modules/Test/') 116 { 117 // use ilStyleDefinition instead of account to get the current skin 118 include_once "Services/Style/System/classes/class.ilStyleDefinition.php"; 119 if (ilStyleDefinition::getCurrentSkin() != "default") { 120 $fname = "./Customizing/global/skin/" . 121 ilStyleDefinition::getCurrentSkin() . "/" . $module_path . basename($a_filename); 122 } 123 124 if ($fname == "" || !file_exists($fname)) { 125 $fname = "./" . $module_path . "templates/default/" . basename($a_filename); 126 } 127 return $fname; 128 } 129 130 protected static function getCssContent() 131 { 132 $cssContent = file_get_contents(self::getTemplatePath('delos.css', '')); 133 $cssContent .= file_get_contents(self::getTemplatePath('test_pdf.css')); 134 135 return $cssContent; 136 } 137} 138