/** * Do the HTML to PDF conversion work * * @param Doku_Event $event * @param array $param * @return bool */ public function convert(&$event, $param) { global $ACT; global $REV; global $ID; // our event? if ($ACT != 'export_pdfbook' && $ACT != 'export_pdf') { return false; } // check user's rights if (auth_quickaclcheck($ID) < AUTH_READ) { return false; } // one or multiple pages? $list = array(); if ($ACT == 'export_pdf') { $list[0] = $ID; $title = p_get_first_heading($ID); } elseif (isset($_COOKIE['list-pagelist']) && !empty($_COOKIE['list-pagelist'])) { //is in Bookmanager of bookcreator plugin title given if (!($title = $_GET['pdfbook_title'])) { //TODO when title is changed, the cached file contains the old title /** @var $bookcreator action_plugin_bookcreator */ $bookcreator = plugin_load('action', 'bookcreator'); msg($bookcreator->getLang('needtitle'), -1); $event->data = 'show'; $_SERVER['REQUEST_METHOD'] = 'POST'; //clears url return false; } $list = explode("|", $_COOKIE['list-pagelist']); } else { /** @var $bookcreator action_plugin_bookcreator */ $bookcreator = plugin_load('action', 'bookcreator'); msg($bookcreator->getLang('empty'), -1); $event->data = 'show'; $_SERVER['REQUEST_METHOD'] = 'POST'; //clears url return false; } // it's ours, no one else's $event->preventDefault(); // prepare cache $cache = new cache(join(',', $list) . $REV . $this->tpl, '.dw2.pdf'); $depends['files'] = array_map('wikiFN', $list); $depends['files'][] = __FILE__; $depends['files'][] = dirname(__FILE__) . '/renderer.php'; $depends['files'][] = dirname(__FILE__) . '/mpdf/mpdf.php'; $depends['files'] = array_merge($depends['files'], getConfigFiles('main')); // hard work only when no cache available if (!$this->getConf('usecache') || !$cache->useCache($depends)) { // initialize PDF library require_once dirname(__FILE__) . "/DokuPDF.class.php"; $mpdf = new DokuPDF(); // let mpdf fix local links $self = parse_url(DOKU_URL); $url = $self['scheme'] . '://' . $self['host']; if ($self['port']) { $url .= ':' . $self['port']; } $mpdf->setBasePath($url); // Set the title $mpdf->SetTitle($title); // some default settings $mpdf->mirrorMargins = 1; $mpdf->useOddEven = 1; $mpdf->setAutoTopMargin = 'stretch'; $mpdf->setAutoBottomMargin = 'stretch'; // load the template $template = $this->load_template($title); // prepare HTML header styles $html = '<html><head>'; $html .= '<style type="text/css">'; $html .= $this->load_css(); $html .= '@page { size:auto; ' . $template['page'] . '}'; $html .= '@page :first {' . $template['first'] . '}'; $html .= '</style>'; $html .= '</head><body>'; $html .= $template['html']; $html .= '<div class="dokuwiki">'; // loop over all pages $cnt = count($list); for ($n = 0; $n < $cnt; $n++) { $page = $list[$n]; $html .= p_cached_output(wikiFN($page, $REV), 'dw2pdf', $page); $html .= $this->page_depend_replacements($template['cite'], cleanID($page)); if ($n < $cnt - 1) { $html .= '<pagebreak />'; } } $html .= '</div>'; $mpdf->WriteHTML($html); // write to cache file $mpdf->Output($cache->cache, 'F'); } // deliver the file header('Content-Type: application/pdf'); header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); header('Pragma: public'); http_conditionalRequest(filemtime($cache->cache)); $filename = rawurlencode(cleanID(strtr($title, ':/;"', ' '))); if ($this->getConf('output') == 'file') { header('Content-Disposition: attachment; filename="' . $filename . '.pdf";'); } else { header('Content-Disposition: inline; filename="' . $filename . '.pdf";'); } if (http_sendfile($cache->cache)) { exit; } $fp = @fopen($cache->cache, "rb"); if ($fp) { http_rangeRequest($fp, filesize($cache->cache), 'application/pdf'); } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read file - bad permissions?"; } exit; }
/** * Build a pdf from the html * * @param string $cachefile * @param string $title */ protected function generatePDF($cachefile, $title) { global $ID; global $REV; global $INPUT; //some shortcuts to export settings $hasToC = $this->getExportConfig('hasToC'); $levels = $this->getExportConfig('levels'); $isDebug = $this->getExportConfig('isDebug'); // initialize PDF library require_once dirname(__FILE__) . "/DokuPDF.class.php"; $mpdf = new DokuPDF($this->getExportConfig('pagesize'), $this->getExportConfig('orientation')); // let mpdf fix local links $self = parse_url(DOKU_URL); $url = $self['scheme'] . '://' . $self['host']; if ($self['port']) { $url .= ':' . $self['port']; } $mpdf->setBasePath($url); // Set the title $mpdf->SetTitle($title); // some default document settings //note: double-sided document, starts at an odd page (first page is a right-hand side page) // single-side document has only odd pages $mpdf->mirrorMargins = $this->getExportConfig('doublesided'); $mpdf->setAutoTopMargin = 'stretch'; $mpdf->setAutoBottomMargin = 'stretch'; // $mpdf->pagenumSuffix = '/'; //prefix for {nbpg} if ($hasToC) { $mpdf->PageNumSubstitutions[] = array('from' => 1, 'reset' => 0, 'type' => 'i', 'suppress' => 'off'); //use italic pageno until ToC $mpdf->h2toc = $levels; } else { $mpdf->PageNumSubstitutions[] = array('from' => 1, 'reset' => 0, 'type' => '1', 'suppress' => 'off'); } // load the template $template = $this->load_template($title); // prepare HTML header styles $html = ''; if ($isDebug) { $html .= '<html><head>'; $html .= '<style type="text/css">'; } $styles = $this->load_css(); $styles .= '@page { size:auto; ' . $template['page'] . '}'; $styles .= '@page :first {' . $template['first'] . '}'; $styles .= '@page landscape-page { size:landscape }'; $styles .= 'div.dw2pdf-landscape { page:landscape-page }'; $styles .= '@page portrait-page { size:portrait }'; $styles .= 'div.dw2pdf-portrait { page:portrait-page }'; $mpdf->WriteHTML($styles, 1); if ($isDebug) { $html .= $styles; $html .= '</style>'; $html .= '</head><body>'; } $body_start = $template['html']; $body_start .= '<div class="dokuwiki">'; // insert the cover page $body_start .= $template['cover']; $mpdf->WriteHTML($body_start, 2, true, false); //start body html if ($isDebug) { $html .= $body_start; } if ($hasToC) { //Note: - for double-sided document the ToC is always on an even number of pages, so that the following content is on a correct odd/even page // - first page of ToC starts always at odd page (so eventually an additional blank page is included before) // - there is no page numbering at the pages of the ToC $mpdf->TOCpagebreakByArray(array('toc-preHTML' => '<h2>' . $this->getLang('tocheader') . '</h2>', 'toc-bookmarkText' => $this->getLang('tocheader'), 'links' => true, 'outdent' => '1em', 'resetpagenum' => true, 'pagenumstyle' => '1')); $html .= '<tocpagebreak>'; } // store original pageid $keep = $ID; // loop over all pages $cnt = count($this->list); for ($n = 0; $n < $cnt; $n++) { $page = $this->list[$n]; // set global pageid to the rendered page $ID = $page; $pagehtml = p_cached_output(wikiFN($page, $REV), 'dw2pdf', $page); $pagehtml .= $this->page_depend_replacements($template['cite'], $page); if ($n < $cnt - 1) { $pagehtml .= '<pagebreak />'; } $mpdf->WriteHTML($pagehtml, 2, false, false); //intermediate body html if ($isDebug) { $html .= $pagehtml; } } //restore ID $ID = $keep; // insert the back page $body_end = $template['back']; $body_end .= '</div>'; $mpdf->WriteHTML($body_end, 2, false, true); // finish body html if ($isDebug) { $html .= $body_end; $html .= '</body>'; $html .= '</html>'; } //Return html for debugging if ($isDebug) { if ($INPUT->str('debughtml', 'text', true) == 'html') { echo $html; } else { header('Content-Type: text/plain; charset=utf-8'); echo $html; } exit; } // write to cache file $mpdf->Output($cachefile, 'F'); }