1<?php 2 3if(!defined('DOKU_PLUGIN')) die('meh'); 4 5if ( intval($_REQUEST['pdfExport']) == 1 && file_exists(DOKU_PLUGIN . 'dw2pdf/mpdf/mpdf.php') ) { 6 7 require_once(DOKU_PLUGIN . 'siteexport/inc/mpdf.php'); 8 class siteexport_pdfgenerator 9 { 10 private $functions; 11 12 public function siteexport_pdfgenerator( $functions=null ) 13 { 14 $this->functions = $functions; 15 } 16 17 function createPDFFromFile($filename, $NAME) { 18 19 if ( !preg_match("/" . $this->settings->fileType . "$/", $NAME) ) { 20 $this->functions->debug->message("Filetype {$this->settings->fileType} did not match filename '$NAME'", null, 4); 21 return false; 22 } 23 24 $mpdf = new siteexportPDF('UTF-8-s', $this->functions->debug); 25 26 if ( !$mpdf ) { 27 $this->functions->debug->message("Could not instantiate MPDF", null, 4); 28 return false; 29 } 30 31 32 $html = file_get_contents($filename); 33 34 if ( !strstr($html, "<html") ) { 35 $this->functions->debug->message("Filecontent had no HTML starting tag", null, 4); 36 return false; 37 } 38 39 // Save HTML too 40 $this->functions->debug->message("Arranging HTML", null, 2); 41 $this->arrangeHtml($html, 'bl,acronym'); 42 $this->functions->debug->message("Done arranging HTML:", $html, 1); 43 44 $fp = fopen($filename, "w"); 45 fwrite($fp, $html); 46 fclose($fp); 47 48 $mpdf->debug = false; 49 $mpdf->list_indent_first_level = 1; // Indents the first level of lists. 50 //$mpdf->SetBasePath("/"); 51 $mpdf->usepre = false; 52 $mpdf->margin_bottom_collapse = true; 53 $mpdf->SetDisplayMode('fullpage'); 54 $mpdf->restoreBlockPageBreaks = true; 55 $this->img_dpi = 300; 56 57 $mpdf->setBasePath(empty($this->functions->settings->depth) ? './' : $this->functions->settings->depth); 58 $mpdf->SetAutoFont(AUTOFONT_ALL); 59 60 // Temp dir 61 62 $mpdf->ignore_invalid_utf8 = true; 63 $mpdf->mirrorMargins = 0; // don't mirror margins 64 $mpdf->WriteHTML($html); 65 $mpdf->Output($filename, "F"); 66 67 $this->functions->debug->message("Used images:", $mpdf->images, 1); 68 $this->functions->debug->message("Failed images:", $mpdf->failedimages, 1); 69 70 return true; 71 } 72 73 function arrangeHtml(&$html, $norendertags = '' ) 74 { 75 global $conf; 76 77 // add bookmark links 78 $html = preg_replace_callback("/<h(\d)(.*?)>(.+?)<\/h\\1>/s", array($this, '__pdfHeaderCallback'), $html); 79 $html = preg_replace_callback("/<\/div>\s*?<h({$conf['plugin']['siteexport']['PDFHeaderPagebreak']})(.*?)>/s", array($this, '__pdfHeaderCallbackPagebreak'), $html); 80 $html = preg_replace("/(<img.*?mediacenter.*?\/>)/", "<table style=\"width:100%; border: 0px solid #000;\"><tr><td style=\"text-align: center\">$1</td></tr></table>", $html); 81 $html = preg_replace("/<p>(\s*?<table.*?<\/table>\s*?)<\/p>/s", "$1", $html); 82 $html = preg_replace_callback("/<pre(.*?)>(.*?)<\/pre>/s", array($this, '__pdfPreCodeCallback'), $html); 83 $html = preg_replace_callback("/<a href=\"mailto:(.*?)\".*?>(.*?)<\/a>/s", array($this, '__pdfMailtoCallback'), $html); 84 /**/ 85 86 $standardReplacer = array ( 87 // insert a pagebreak for support of WRAP and PAGEBREAK plugins 88 '<br style="page-break-after:always;">' => '<pagebreak />', 89 '<div class="wrap_pagebreak"></div>' => '<pagebreak />', 90 '<sup>' => '<sup class="sup">', 91 '<sub>' => '<sub class="sub">', 92 '<code>' => '<code class="code">' 93 ); 94 $html = str_replace(array_keys($standardReplacer), array_values($standardReplacer), $html); 95 96 // thanks to Jared Ong 97 // Customized to strip all span tags so that the wiki <code> SQL would display properly 98 $norender = explode(',',$norendertags); 99 $html = $this->strip_only($html, $norender ); //array('span','acronym')); 100 $html = $this->strip_htmlencodedchars($html); 101 // Customized to strip all span tags so that the wiki <code> SQL would display properly 102 } 103 104 private function __pdfMailtoCallback($DATA) { 105 if ( $DATA[1] == $DATA[2] ) { 106 $DATA[2] = $this->deobfuscate($DATA[2]); 107 } 108 $DATA[1] = $this->deobfuscate($DATA[1]); 109 return "<a href=\"mailto:{$DATA[1]}\">{$DATA[2]}</a>"; 110 } 111 112 private function __pdfPreCodeCallback($DATA) { 113 114 $code = nl2br($DATA[2]); 115 $code = preg_replace_callback("/(^|<br \/>)(\s+)(\S)/s", array($this, '__pdfPreWhitespacesCallback'), $code); 116 117 return "\n<pre" . $DATA[1] . ">\n" . $code . "\n</pre>\n"; 118 } 119 120 private function __pdfPreWhitespacesCallback( $DATA ) { 121 return $DATA[1] . "\n" . str_repeat(" ", strlen($DATA[2])-($DATA[2]{0}=="\n"?1:0) ) . $DATA[3]; 122 } 123 124 private function __pdfHeaderCallback($DATA) { 125 $contentText = $this->xmlEntities(preg_replace("/<\/?.*?>/s", '', $DATA[3])); // Double encoding - has to be decoded in mpdf once more. 126 return '<tocentry content="' . $contentText . '" level="' . ($DATA[1]-1) . '" /><bookmark content="' . $contentText . '" level="' . ($DATA[1]-1) . '" /><h' . $DATA[1] . $DATA[2] . '>' . $DATA[3] . '</h' . $DATA[1] . '>'; 127 } 128 129 private function __pdfHeaderCallbackPagebreak($DATA) { 130 return '</div>' . "\r\n" . '<pagebreak />' . "\r\n\r\n" . '<h' . $DATA[1] . $DATA[2] . '>'; 131 } 132 // thanks to Jared Ong 133 // Custom function for help in stripping span tags 134 private function strip_only($str, $tags) { 135 if(!is_array($tags)) { 136 $tags = (strpos($str, '>') !== false ? explode('>', str_replace('<', '', $tags)) : array($tags)); 137 if(end($tags) == '') array_pop($tags); 138 } 139 140 foreach($tags as $tag) $str = preg_replace('#</?'.$tag.'[^>]*>#is', '', $str); 141 return $str; 142 } 143 // Custom function for help in stripping span tags 144 145 // Custom function for help in replacing ' " > < & 146 private function strip_htmlencodedchars($str) { 147 $str = str_replace(''', '\'', $str); 148 // $str = str_replace('"', '"', $str); 149 // $str = str_replace('>', '>', $str); 150 // $str = str_replace('<', '<', $str); 151 // $str = str_replace('&', '&', $str); 152 return $str; 153 } 154 // Custom function for help in replacing ' " > < & 155 156 /** 157 * return an de-obfuscated email address in line with $conf['mailguard'] setting 158 */ 159 private function deobfuscate($email) { 160 global $conf; 161 162 switch ($conf['mailguard']) { 163 case 'visible' : 164 $obfuscate = array(' [at] ' => '@', ' [dot] ' => '.', ' [dash] ' => '-'); 165 return strtr($email, $obfuscate); 166 167 case 'hex' : 168 $encode = ''; 169 $len = strlen($email); 170 for ($x=0; $x < $len; $x+=6){ 171 $encode .= chr(hexdec($email{$x+3}.$email{($x+4)})); 172 } 173 return $encode; 174 175 case 'none' : 176 default : 177 return $email; 178 } 179 } 180 181 /** 182 * Encoding ()taken from DW - but without needing the renderer 183 **/ 184 private function xmlEntities($string) { 185 return htmlspecialchars($string,ENT_QUOTES,'UTF-8'); 186 } 187 } 188} 189?>