Extension:Pdf Export Dompdf
From MediaWiki.org
|
Release status: beta |
|
|---|---|
| Description | Converts current page to PDF and sends to browser, using dompdf (a html to pdf converter written in php5) |
| Author(s) | Andreas Hagmann (AhTalk)
Craig Oakes (DumpydoobyTalk) |
| MediaWiki | 1.12+ |
| License | No license specified |
| Download | Code |
|
check usage (experimental) |
|
Contents |
[edit] Overview
This extension is a modified version of the Pdf_Export Extension. See Extension:Pdf_Export for details.
I modified it because I wanted to do pdf-export on my shared hosting server. It was impossible to install htmldoc on it because I dont't have root access.
Searching the web, I found dompdf, an html to pdf converter written in php5.
[edit] Installation
Follow each step in order, and review the linked items as needed.
- Install the original Pdf Export
- Overwrite $IP/extensions/PdfExport/PdfExport_body.php
- Note: All modifications to original code have been noted in my source to make it easy to track my code.
- Create $IP/extensions/PdfExport/PdfExport_headfoot.php
- Install dompdf
- Extract dompdf to $IP/extensions/PdfExport/dompdf/
- Add the following to LocalSettings.php:
require_once("$IP/extensions/PdfExport/PdfExport.php"); $PdfExportUseHtmlDoc = false;
- Note: The above value can be changed to true if you would like to revert to using HtmlDoc (I use is_executable() as a failsafe, just in case this value set to true, but HtmlDoc is not installed.
[edit] Code
Create or edit the following files accordingly.
[edit] PdfExport_body.php
Put the following into $IP/extensions/PdfExport/PdfExport_body.php:
<?php # This file has been modified by DumpyDooby. if ( !defined( 'MEDIAWIKI' ) ) die(); # <Craig> $PdfExportUseHtmlDoc = isset($PdfExportUseHtmlDoc) ? $PdfExportUseHtmlDoc : false; # </Craig> $wgPdfExportAttach = false; // set to true if you want output as an attachment $wgPdfExportHttpsImages = false; // set to true if page is on a HTTPS server and contains images that are on the HTTPS server and also // reachable with HTTP class SpecialPdf extends SpecialPage { var $title; var $article; var $html; var $parserOptions; var $bhtml; public $iswindows; function SpecialPdf() { global $iswindows; SpecialPage::SpecialPage( 'PdfPrint' ); $os = getenv ("SERVER_SOFTWARE"); $iswindows = strstr ($os, "Win32"); } public function write1file ($text) { // make a temporary directory with an unique name // NOTE: If no PDF file is created and you get message "ERROR: No HTML files!", // try using a temporary directory that is within web server space. // For example (assuming the web server root directory is /var/www/html): // $mytemp = "/var/html/www/tmp/f" .time(). "-" .rand() . ".html"; # <Craig> $mytemp=tempnam(sys_get_temp_dir(), 'PdfExport'); # </Craig> $article_f = fopen($mytemp,'w'); if($article_f === FALSE){ error_log("Failed opening temporary HTML file to \"$mytemp\" failed", 0); return; } fwrite($article_f, $text); # <Craig> fseek($article_f, 0); # </Craig> fclose($article_f); return $mytemp; } public function save1page ( $page ) { global $wgUser; global $wgParser; global $wgScriptPath; global $wgServer; global $wgPdfExportHttpsImages; $title = Title::newFromText( $page ); if( is_null( $title ) || !$title->userCanRead() ) return null; $article = new Article ($title); $parserOptions = ParserOptions::newFromUser( $wgUser ); $parserOptions->setEditSection( false ); $parserOptions->setTidy(true); $wgParser->mShowToc = false; $parserOutput = $wgParser->parse( $article->preSaveTransform( $article->getContent() ) ."\n\n", $title, $parserOptions ); $bhtml = $parserOutput->getText(); // Hack to thread the EUR sign correctly $bhtml = str_replace(chr(0xE2) . chr(0x82) . chr(0xAC), chr(0xA4), $bhtml); $bhtml = utf8_decode($bhtml); $bhtml = str_replace ($wgScriptPath, $wgServer . $wgScriptPath, $bhtml); $bhtml = str_replace ('/w/',$wgServer . '/w/', $bhtml); if ($wgPdfExportHttpsImages) $bhtm = str_replace('img src=\"https:\/\/','img src=\"http:\/\/', $bhtml); $html = "<html><head><title>" . utf8_decode($page) . "</title></head><body>" . $bhtml . "</body></html>"; return $this->write1file ($html); } function outputpdf ($pages, $landscape, $size) { global $iswindows; global $wgPdfExportAttach; $returnStatus = 0; $pagestring = ""; $pagefiles = array(); $foundone = false; foreach ($pages as $pg) { $f = $this->save1page ($pg); if ($f == null) continue; $foundone = true; if ($iswindows) $pagestring .= "\"" . $f . "\" "; else $pagestring .= $f . " "; $pagefiles[] = $f; } if ($foundone == false) return; putenv("HTMLDOC_NOCGI=1"); # Write the content type to the client... header("Content-Type: application/pdf"); if ($wgPdfExportAttach) header(sprintf('Content-Disposition: attachment; filename="%s.pdf"', $page)); # <Craig> global $PdfExportUseHtmlDoc; if($PdfExportUseHtmlDoc == true && is_executable('htmldoc')){ # Run HTMLDOC to provide the PDF file to the user... passthru("htmldoc -t pdf14 --charset iso-8859-15 --color --quiet --jpeg --size " . $size . " " . $landscape . "--webpage " . $pagestring, $returnStatus); if($returnStatus == 1) error_log("Generating PDF failed. Return status was:" . $returnStatus, 0); } else{ $PdfContent = ''; foreach ($pagefiles as &$pagefile){ $PdfContent .= file_get_contents($pagefile); } //Note: Create PdfExport_headfoot.php if necessary (it can be blank). $PdfHeaderFooter = '<script type="text/php">include_once("'.realpath(dirname(__FILE__)).'/PdfExport_headfoot.php");</script>'; $PdfContent = str_replace('</body></html>',$PdfHeaderFooter.'</body></html>',$PdfContent); // Insert inline header/footer script. $PdfContent = str_replace('</head>','<style type="text/css">body{padding:10px 10px 35px;}</style></head>',$PdfContent); // Insert styling to make room for header/footer. $orientation = stristr($landscape,'landscape') ? 'landscape' : 'portrait'; // Required API for alternative method. // Download here: http://www.digitaljunkies.ca/dompdf/downloads.php require_once( realpath(dirname(__FILE__)) . "/dompdf/dompdf_config.inc.php" ); spl_autoload_register( 'DOMPDF_autoload' ); $domPDF = new DOMPDF(); $domPDF->set_base_path(realpath(dirname(__FILE__)).'/tmp'); $domPDF->set_paper(mb_strtolower($size), mb_strtolower($orientation)); $domPDF->load_html($PdfContent); $domPDF->render(); $domPDF->stream(utf8_decode($page) . ".pdf", array('Attachment'=>0)); } # </Craig> flush(); foreach ($pagefiles as $pgf) { unlink ($pgf); } } function execute( $par ) { global $wgRequest; global $wgOut; wfLoadExtensionMessages ('PdfPrint'); $dopdf = false; if ($wgRequest->wasPosted()) { $pagel = $wgRequest->getText ('pagel'); $pages = array_filter( explode( "\n", $pagel ), 'wfFilterPage1' ); $size = $wgRequest->getText ('Size', 'Letter'); $orientations = $wgRequest->getVal ('orientation'); $orientation = ($orientations == 'landscape') ? " --landscape --browserwidth 1200 " : " --portrait "; $dopdf = true; } else { $page = isset( $par ) ? $par : $wgRequest->getText( 'page' ); if ($page != "") $dopdf = true; $pages = array ($page); $orientation = " --portrait "; $size = "Letter"; } if ($dopdf) { $wgOut->setPrintable(); $wgOut->disable(); $this->outputpdf ($pages, $orientation, $size); return; } $self = SpecialPage::getTitleFor( 'PdfPrint' ); $wgOut->addHtml( wfMsgExt( 'pdf_print_text', 'parse' ) ); $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $self->getLocalUrl( 'action=submit' ) ) ); $form .= Xml::openElement( 'textarea', array( 'name' => 'pagel', 'cols' => 40, 'rows' => 10 ) ); $form .= Xml::closeElement( 'textarea' ); $form .= '<br />'; $form .= Xml::radioLabel(wfMsg ('pdf_portrait'), 'orientation' , 'portrait' , 'portrait', true); $form .= Xml::radioLabel(wfMsg ('pdf_landscape'), 'orientation' , 'landscape' , 'landscape', false); $form .= '<br />' . wfMsg('pdf_size'); $form .= Xml::listDropDown ('Size', wfMsg ('pdf_size_options'),'', wfMsg('pdf_size_default')); $form .= Xml::submitButton( wfMsg( 'pdf_submit' ) ); $form .= Xml::closeElement( 'form' ); $wgOut->addHtml( $form ); } } function wfFilterPage1( $page ) { return $page !== '' && $page !== null; }
[edit] PdfExport_headfoot.php
Put the following into $IP/extensions/PdfExport/PdfExport_headfoot.php:
<?php if(isset($pdf)){ $font = Font_Metrics::get_font("verdana"); $size = 10; $color = array(0,0,0); $text_height = Font_Metrics::get_font_height($font, $size); $foot = $pdf->open_object(); $w = $pdf->get_width(); $h = $pdf->get_height(); $y = $h - 2 * $text_height - 24; $pdf->line(16, $y, $w - 16, $y, $color, 1); $y += $text_height; $text = "My Awesome Website! (edit PdfExport_headfoot.php to change this text) | " . date("F j, Y"); $pdf->text(16, $y, $text, $font, $size, $color); $pdf->close_object(); $pdf->add_object($foot, "all"); $text = "Page {PAGE_NUM}/{PAGE_COUNT}"; $width = Font_Metrics::get_text_width($text, $font, $size); $pdf->page_text($w-5 - $width, $y, $text, $font, $size, $color); }
[edit] See also
- Extension:Collection - allows to build collections from a number of pages. Collections can be edited, persisted and retrieved as PDF. No need to install dompdf or htmldoc.