17d101cc1SGerry Weißbach<?php 27d101cc1SGerry Weißbach 37d101cc1SGerry Weißbachif (!defined('DOKU_PLUGIN')) die('meh'); 47d101cc1SGerry Weißbach 5*56c4b32dSGerry Weißbachif (!function_exists('siteexport_dw2pdf_has_mpdf_engine')) { 6*56c4b32dSGerry Weißbach /** 7*56c4b32dSGerry Weißbach * True if dw2pdf ships an mPDF we can use (legacy bundled mpdf/ or Composer vendor/ + DokuPDF). 8*56c4b32dSGerry Weißbach */ 9*56c4b32dSGerry Weißbach function siteexport_dw2pdf_has_mpdf_engine() 10*56c4b32dSGerry Weißbach { 11*56c4b32dSGerry Weißbach if (file_exists(DOKU_PLUGIN . 'dw2pdf/mpdf/mpdf.php')) { 12*56c4b32dSGerry Weißbach return true; 13*56c4b32dSGerry Weißbach } 14*56c4b32dSGerry Weißbach return file_exists(DOKU_PLUGIN . 'dw2pdf/vendor/autoload.php') 15*56c4b32dSGerry Weißbach && file_exists(DOKU_PLUGIN . 'dw2pdf/DokuPDF.class.php'); 16*56c4b32dSGerry Weißbach } 17*56c4b32dSGerry Weißbach} 18*56c4b32dSGerry Weißbach 19*56c4b32dSGerry Weißbachif (!empty($_REQUEST['pdfExport']) && intval($_REQUEST['pdfExport']) == 1 && siteexport_dw2pdf_has_mpdf_engine()) { 207d101cc1SGerry Weißbach 217d101cc1SGerry Weißbach require_once(DOKU_PLUGIN . 'siteexport/inc/mpdf.php'); 227d101cc1SGerry Weißbach class siteexport_pdfgenerator 237d101cc1SGerry Weißbach { 247d101cc1SGerry Weißbach private $functions; 257d101cc1SGerry Weißbach 26b324a190SMichael Hamann public function __construct($functions = null) 277d101cc1SGerry Weißbach { 287d101cc1SGerry Weißbach $this->functions = $functions; 297d101cc1SGerry Weißbach } 307d101cc1SGerry Weißbach 31a8c17ab5Si-net /// software public function createPDFFromFile($filename, &$NAME) { 327d101cc1SGerry Weißbach 33022fb779Si-net /// software global $INPUT; 34022fb779Si-net /// software 35a8c17ab5Si-net /// software if (!preg_match("/" . $this->functions->settings->fileType . "$/", $NAME)) { 36a8c17ab5Si-net /// software $this->functions->debug->message("Filetype " . $this->functions->settings->fileType . " did not match filename '$NAME'", null, 4); 377d101cc1SGerry Weißbach return false; 387d101cc1SGerry Weißbach } 397d101cc1SGerry Weißbach 407f6f0f99SGerry Weißbach $mpdf = new siteexportPDF($this->functions->debug); 417d101cc1SGerry Weißbach 427d101cc1SGerry Weißbach if (!$mpdf) { 437d101cc1SGerry Weißbach $this->functions->debug->message("Could not instantiate MPDF", null, 4); 447d101cc1SGerry Weißbach return false; 457d101cc1SGerry Weißbach } 467d101cc1SGerry Weißbach 47e6ebb3b0SGerry Weißbach $html = @file_get_contents($filename); 487d101cc1SGerry Weißbach 497d101cc1SGerry Weißbach if (!strstr($html, "<html")) { 507d101cc1SGerry Weißbach $this->functions->debug->message("Filecontent had no HTML starting tag", null, 4); 517d101cc1SGerry Weißbach return false; 527d101cc1SGerry Weißbach } 537d101cc1SGerry Weißbach 547d101cc1SGerry Weißbach // Save HTML too 557d101cc1SGerry Weißbach $this->functions->debug->message("Arranging HTML", null, 2); 567d101cc1SGerry Weißbach $this->arrangeHtml($html, 'bl,acronym'); 577d101cc1SGerry Weißbach $this->functions->debug->message("Done arranging HTML:", $html, 1); 587d101cc1SGerry Weißbach 59a4a5b91dSGerry Weißbach $mpdf->debug = false; 607d101cc1SGerry Weißbach $mpdf->list_indent_first_level = 1; // Indents the first level of lists. 61a8c17ab5Si-net /// software 62*56c4b32dSGerry Weißbach // Legacy mPDF only; omitted with mPDF 8 / DokuPDF 63*56c4b32dSGerry Weißbach if (property_exists($mpdf, 'usepre')) { 647d101cc1SGerry Weißbach $mpdf->usepre = false; 65*56c4b32dSGerry Weißbach } 667d101cc1SGerry Weißbach $mpdf->margin_bottom_collapse = true; 677d101cc1SGerry Weißbach $mpdf->SetDisplayMode('fullpage'); 68*56c4b32dSGerry Weißbach if (property_exists($mpdf, 'restoreBlockPageBreaks')) { 697d101cc1SGerry Weißbach $mpdf->restoreBlockPageBreaks = true; 70*56c4b32dSGerry Weißbach } 71022fb779Si-net /// software 72022fb779Si-net /// software $mpdf->dpi = $INPUT->int('dpi', 96, true); 73022fb779Si-net /// software $mpdf->img_dpi = $INPUT->int('dpi', 96, true); 747d101cc1SGerry Weißbach 75a4a5b91dSGerry Weißbach $mpdf->setBasePath(empty($this->functions->settings->depth) ? './' : $this->functions->settings->depth); 767d101cc1SGerry Weißbach 777d101cc1SGerry Weißbach $mpdf->ignore_invalid_utf8 = true; 78876523d1SGerry Weißbach $mpdf->mirrorMargins = $this->functions->getConf('useOddEven'); // don't mirror margins 79876523d1SGerry Weißbach $mpdf->setAutoTopMargin = 'pad'; 80876523d1SGerry Weißbach $mpdf->setAutoBottomMargin = 'pad'; 818914cf7eSGerry Weißbach 827d101cc1SGerry Weißbach $mpdf->WriteHTML($html); 837d101cc1SGerry Weißbach $mpdf->Output($filename, "F"); 84a8c17ab5Si-net /// software 85e6ebb3b0SGerry Weißbach return $html; 867d101cc1SGerry Weißbach } 877d101cc1SGerry Weißbach 88a8c17ab5Si-net /// software private function arrangeHtml(&$html, $norendertags = '') 897d101cc1SGerry Weißbach { 907d101cc1SGerry Weißbach global $conf; 917d101cc1SGerry Weißbach 927d101cc1SGerry Weißbach // add bookmark links 9306a6f0adSGerry Weißbach $html = preg_replace_callback("/<h(\d)(.*?)>(.*?)<\/h\\1>/s", array($this, '__pdfHeaderCallback'), $html); 947d101cc1SGerry Weißbach $html = preg_replace_callback("/<\/div>\s*?<h({$conf['plugin']['siteexport']['PDFHeaderPagebreak']})(.*?)>/s", array($this, '__pdfHeaderCallbackPagebreak'), $html); 957d101cc1SGerry Weißbach $html = preg_replace("/(<img.*?mediacenter.*?\/>)/", "<table style=\"width:100%; border: 0px solid #000;\"><tr><td style=\"text-align: center\">$1</td></tr></table>", $html); 96e7fd0196SGerry Weißbach 97e7fd0196SGerry Weißbach // Remove p arround img and table 98e7fd0196SGerry Weißbach $html = preg_replace("/<p[^>]*?>(\s*?<img[^>]*?\/?>\s*?)<\/p>/s", "$1", $html); 99e7fd0196SGerry Weißbach $html = preg_replace("/<p[^>]*?>(\s*?<table.*?<\/table>\s*?)<\/p>/s", "$1", $html); 1007d101cc1SGerry Weißbach $html = preg_replace_callback("/<pre(.*?)>(.*?)<\/pre>/s", array($this, '__pdfPreCodeCallback'), $html); 1017d101cc1SGerry Weißbach $html = preg_replace_callback("/<a href=\"mailto:(.*?)\".*?>(.*?)<\/a>/s", array($this, '__pdfMailtoCallback'), $html); 1027d101cc1SGerry Weißbach /**/ 1037d101cc1SGerry Weißbach 1047d101cc1SGerry Weißbach $standardReplacer = array( 1057d101cc1SGerry Weißbach // insert a pagebreak for support of WRAP and PAGEBREAK plugins 1067d101cc1SGerry Weißbach '<br style="page-break-after:always;">' => '<pagebreak />', 1077d101cc1SGerry Weißbach '<div class="wrap_pagebreak"></div>' => '<pagebreak />', 1087d101cc1SGerry Weißbach '<sup>' => '<sup class="sup">', 1097d101cc1SGerry Weißbach '<sub>' => '<sub class="sub">', 1106792d0cfSGerry Weißbach '<code>' => '<code class="code">' 1117d101cc1SGerry Weißbach ); 1127d101cc1SGerry Weißbach $html = str_replace(array_keys($standardReplacer), array_values($standardReplacer), $html); 1137d101cc1SGerry Weißbach 1147d101cc1SGerry Weißbach // thanks to Jared Ong 1157d101cc1SGerry Weißbach // Customized to strip all span tags so that the wiki <code> SQL would display properly 1167d101cc1SGerry Weißbach $norender = explode(',', $norendertags); 1177d101cc1SGerry Weißbach $html = $this->strip_only($html, $norender); //array('span','acronym')); 1187d101cc1SGerry Weißbach $html = $this->strip_htmlencodedchars($html); 1197d101cc1SGerry Weißbach // Customized to strip all span tags so that the wiki <code> SQL would display properly 1207d101cc1SGerry Weißbach } 1217d101cc1SGerry Weißbach 1227d101cc1SGerry Weißbach private function __pdfMailtoCallback($DATA) { 1237d101cc1SGerry Weißbach if ($DATA[1] == $DATA[2]) { 1247d101cc1SGerry Weißbach $DATA[2] = $this->deobfuscate($DATA[2]); 1257d101cc1SGerry Weißbach } 1267d101cc1SGerry Weißbach $DATA[1] = $this->deobfuscate($DATA[1]); 1277d101cc1SGerry Weißbach return "<a href=\"mailto:{$DATA[1]}\">{$DATA[2]}</a>"; 1287d101cc1SGerry Weißbach } 1297d101cc1SGerry Weißbach 1307d101cc1SGerry Weißbach private function __pdfPreCodeCallback($DATA) { 1317d101cc1SGerry Weißbach 1327d101cc1SGerry Weißbach $code = nl2br($DATA[2]); 1337d101cc1SGerry Weißbach $code = preg_replace_callback("/(^|<br \/>)(\s+)(\S)/s", array($this, '__pdfPreWhitespacesCallback'), $code); 1347d101cc1SGerry Weißbach 1357d101cc1SGerry Weißbach return "\n<pre" . $DATA[1] . ">\n" . $code . "\n</pre>\n"; 1367d101cc1SGerry Weißbach } 1377d101cc1SGerry Weißbach 1387d101cc1SGerry Weißbach private function __pdfPreWhitespacesCallback($DATA) { 13969bdc716SGerry Weißbach return $DATA[1] . "\n" . str_repeat(" ", strlen($DATA[2])-($DATA[2][0] == "\n" ? 1 : 0)) . $DATA[3]; 1407d101cc1SGerry Weißbach } 1417d101cc1SGerry Weißbach 1427d101cc1SGerry Weißbach private function __pdfHeaderCallback($DATA) { 143984a49eaSGerry Weißbach $contentText = htmlspecialchars_decode(preg_replace("/<\/?.*?>/s", '', $DATA[3]), ENT_NOQUOTES); // 2014-07-23 Do not encode again. or ä -> &auml; 144876523d1SGerry Weißbach return '<h' . $DATA[1] . $DATA[2] . '><tocentry content="' . $contentText . '" level="' . ($DATA[1]-1) . '" /><bookmark content="' . $contentText . '" level="' . ($DATA[1]-1) . '" />' . $DATA[3] . '</h' . $DATA[1] . '>'; 1457d101cc1SGerry Weißbach } 1467d101cc1SGerry Weißbach 1477d101cc1SGerry Weißbach private function __pdfHeaderCallbackPagebreak($DATA) { 1487d101cc1SGerry Weißbach return '</div>' . "\r\n" . '<pagebreak />' . "\r\n\r\n" . '<h' . $DATA[1] . $DATA[2] . '>'; 1497d101cc1SGerry Weißbach } 1507d101cc1SGerry Weißbach // thanks to Jared Ong 1517d101cc1SGerry Weißbach // Custom function for help in stripping span tags 1527d101cc1SGerry Weißbach private function strip_only($str, $tags) { 1537d101cc1SGerry Weißbach if (!is_array($tags)) { 1547d101cc1SGerry Weißbach $tags = (strpos($str, '>') !== false ? explode('>', str_replace('<', '', $tags)) : array($tags)); 1557d101cc1SGerry Weißbach if (end($tags) == '') array_pop($tags); 1567d101cc1SGerry Weißbach } 1577d101cc1SGerry Weißbach 1587d101cc1SGerry Weißbach foreach ($tags as $tag) $str = preg_replace('#</?' . $tag . '[^>]*>#is', '', $str); 1597d101cc1SGerry Weißbach return $str; 1607d101cc1SGerry Weißbach } 1617d101cc1SGerry Weißbach // Custom function for help in stripping span tags 1627d101cc1SGerry Weißbach 1637d101cc1SGerry Weißbach // Custom function for help in replacing ' " > < & 1647d101cc1SGerry Weißbach private function strip_htmlencodedchars($str) { 1657d101cc1SGerry Weißbach $str = str_replace(''', '\'', $str); 1667d101cc1SGerry Weißbach return $str; 1677d101cc1SGerry Weißbach } 1687d101cc1SGerry Weißbach // Custom function for help in replacing ' " > < & 1697d101cc1SGerry Weißbach 1707d101cc1SGerry Weißbach /** 1717d101cc1SGerry Weißbach * return an de-obfuscated email address in line with $conf['mailguard'] setting 1727d101cc1SGerry Weißbach */ 1737d101cc1SGerry Weißbach private function deobfuscate($email) { 1747d101cc1SGerry Weißbach global $conf; 1757d101cc1SGerry Weißbach 1767d101cc1SGerry Weißbach switch ($conf['mailguard']) { 1777d101cc1SGerry Weißbach case 'visible' : 178a8c17ab5Si-net /// software return /** @scrutinizer ignore-call */ strtr($email, array(' [at] ' => '@', ' [dot] ' => '.', ' [dash] ' => '-')); 1797d101cc1SGerry Weißbach 1807d101cc1SGerry Weißbach case 'hex' : 1817d101cc1SGerry Weißbach $encode = ''; 1827d101cc1SGerry Weißbach $len = strlen($email); 1837d101cc1SGerry Weißbach for ($x = 0; $x < $len; $x += 6) { 184892afd94SGerry Weißbach $encode .= chr((int)hexdec($email[$x+3] . $email[$x+4])); 1857d101cc1SGerry Weißbach } 1867d101cc1SGerry Weißbach return $encode; 1877d101cc1SGerry Weißbach 1887d101cc1SGerry Weißbach case 'none' : 1897d101cc1SGerry Weißbach default : 1907d101cc1SGerry Weißbach return $email; 1917d101cc1SGerry Weißbach } 1927d101cc1SGerry Weißbach } 1937d101cc1SGerry Weißbach } 1947d101cc1SGerry Weißbach} 195