r41247 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r41246‎ | r41247 | r41248 >
Date:10:50, 25 September 2008
Author:nad
Status:old
Tags:
Comment:
This extension is quite popular, so moving into official repo
Modified paths:
  • /trunk/extensions/PdfBook (added) (history)
  • /trunk/extensions/PdfBook/PdfBook.php (added) (history)

Diff [purge]

Index: trunk/extensions/PdfBook/PdfBook.php
@@ -0,0 +1,208 @@
 2+<?php
 3+/**
 4+ * PdfBook extension
 5+ * - Composes a book from articles in a category and exports as a PDF book
 6+ *
 7+ * See http://www.mediawiki.org/Extension:PdfBook for installation and usage details
 8+ * See http://www.organicdesign.co.nz/Extension_talk:PdfBook for development notes and disucssion
 9+ *
 10+ * Started: 2007-08-08
 11+ *
 12+ * @package MediaWiki
 13+ * @subpackage Extensions
 14+ * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad]
 15+ * @copyright © 2007 Aran Dunkley
 16+ * @licence GNU General Public Licence 2.0 or later
 17+ */
 18+if (!defined('MEDIAWIKI')) die('Not an entry point.');
 19+
 20+define('PDFBOOK_VERSION', '1.0.0, 2008-09-25');
 21+
 22+$wgPdfBookMagic = "book";
 23+$wgExtensionFunctions[] = 'wfSetupPdfBook';
 24+$wgHooks['LanguageGetMagic'][] = 'wfPdfBookLanguageGetMagic';
 25+
 26+$wgExtensionCredits['parserhook'][] = array(
 27+ 'name' => 'Pdf Book',
 28+ 'author' => '[http://www.organicdesign.co.nz/nad User:Nad]',
 29+ 'description' => 'Composes a book from articles in a category and exports as a PDF book',
 30+ 'url' => 'http://www.mediawiki.org/wiki/Extension:Pdf_Book',
 31+ 'version' => PDFBOOK_VERSION
 32+ );
 33+
 34+class PdfBook {
 35+
 36+ /**
 37+ * Constructor
 38+ */
 39+ function PdfBook() {
 40+ global $wgHooks, $wgParser, $wgPdfBookMagic;
 41+ global $wgLogTypes, $wgLogNames, $wgLogHeaders, $wgLogActions;
 42+ $wgParser->setFunctionHook($wgPdfBookMagic, array($this, 'magicBook'));
 43+ $wgHooks['UnknownAction'][] = $this;
 44+
 45+ # Add a new pdf log type
 46+ $wgLogTypes[] = 'pdf';
 47+ $wgLogNames ['pdf'] = 'pdflogpage';
 48+ $wgLogHeaders['pdf'] = 'pdflogpagetext';
 49+ $wgLogActions['pdf/book'] = 'pdflogentry';
 50+ }
 51+
 52+ /**
 53+ * Expand the book-magic
 54+ * (not used yet)
 55+ */
 56+ function magicBook(&$parser) {
 57+
 58+ # Populate $argv with both named and numeric parameters
 59+ $argv = array();
 60+ foreach (func_get_args() as $arg) if (!is_object($arg)) {
 61+ if (preg_match('/^(.+?)\\s*=\\s*(.+)$/', $arg, $match)) $argv[$match[1]] = $match[2]; else $argv[] = $arg;
 62+ }
 63+
 64+ return $text;
 65+ }
 66+
 67+ /**
 68+ * Perform the export operation
 69+ */
 70+ function onUnknownAction($action,$article) {
 71+ global $wgOut, $wgUser, $wgTitle, $wgParser;
 72+ global $wgServer, $wgArticlePath, $wgScriptPath, $wgUploadPath, $wgUploadDirectory, $wgScript;
 73+
 74+ if ($action == 'pdfbook') {
 75+
 76+ # Log the export
 77+ $msg = $wgUser->getUserPage()->getPrefixedText().' exported as a PDF book';
 78+ $log = new LogPage('pdf', false);
 79+ $log->addEntry('book', $wgTitle, $msg);
 80+
 81+ # Initialise PDF variables
 82+ $layout = '--firstpage toc';
 83+ $left = $this->setProperty('LeftMargin', '1cm');
 84+ $right = $this->setProperty('RightMargin', '1cm');
 85+ $top = $this->setProperty('TopMargin', '1cm');
 86+ $bottom = $this->setProperty('BottomMargin','1cm');
 87+ $font = $this->setProperty('Font', 'Arial');
 88+ $size = $this->setProperty('FontSize', '8');
 89+ $link = $this->setProperty('LinkColour', '217A28');
 90+ $levels = $this->setProperty('TocLevels', '2');
 91+ $exclude = $this->setProperty('Exclude', array());
 92+ if (!is_array($exclude)) $exclude = split('\\s*,\\s*', $exclude);
 93+
 94+ # Select articles from members if a category or links in content if not
 95+ $articles = array();
 96+ $title = $article->getTitle();
 97+ $opt = ParserOptions::newFromUser($wgUser);
 98+ if ($title->getNamespace() == NS_CATEGORY) {
 99+ $db = &wfGetDB(DB_SLAVE);
 100+ $cat = $db->addQuotes($title->getDBkey());
 101+ $result = $db->select(
 102+ 'categorylinks',
 103+ 'cl_from',
 104+ "cl_to = $cat",
 105+ 'PdfBook',
 106+ array('ORDER BY' => 'cl_sortkey')
 107+ );
 108+ if ($result instanceof ResultWrapper) $result = $result->result;
 109+ while ($row = $db->fetchRow($result)) $articles[] = Title::newFromID($row[0]);
 110+ }
 111+ else {
 112+ $text = $article->fetchContent();
 113+ $text = $wgParser->preprocess($text,$title,$opt);
 114+ if (preg_match_all('/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m',$text,$links))
 115+ foreach ($links[1] as $link) $articles[] = Title::newFromText($link);
 116+ }
 117+
 118+ # Format the article's as a single HTML document with absolute URL's
 119+ $book = $title->getText();
 120+ $html = '';
 121+ $wgArticlePath = $wgServer.$wgArticlePath;
 122+ $wgScriptPath = $wgServer.$wgScriptPath;
 123+ $wgUploadPath = $wgServer.$wgUploadPath;
 124+ $wgScript = $wgServer.$wgScript;
 125+ foreach ($articles as $title) {
 126+ $ttext = $title->getPrefixedText();
 127+ if (!in_array($ttext, $exclude)) {
 128+ $article = new Article($title);
 129+ $text = $article->fetchContent();
 130+ $text = preg_replace('/<!--([^@]+?)-->/s', '@@'.'@@$1@@'.'@@', $text); # preserve HTML comments
 131+ $text .= '__NOTOC__';
 132+ $opt->setEditSection(false); # remove section-edit links
 133+ $wgOut->setHTMLTitle($ttext); # use this so DISPLAYTITLE magic works
 134+ $out = $wgParser->parse($text, $title, $opt, true, true);
 135+ $ttext = $wgOut->getHTMLTitle();
 136+ $text = $out->getText();
 137+ $text = preg_replace('|(<img[^>]+?src=")(/.+?>)|', "$1$wgServer$2", $text); # make image urls absolute
 138+ $text = preg_replace('|<div\s*class=[\'"]?noprint["\']?>.+?</div>|s', '', $text); # non-printable areas
 139+ $text = preg_replace('|@{4}([^@]+?)@{4}|s', '<!--$1-->', $text); # HTML comments hack
 140+ $text = preg_replace('|<table|', '<table border borderwidth=2 cellpadding=3 cellspacing=0', $text);
 141+ $ttext = basename($ttext);
 142+ $html .= utf8_decode("<h1>$ttext</h1>$text\n");
 143+ }
 144+ }
 145+
 146+ # If format=html in query-string, return html content directly
 147+ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'html') {
 148+ $wgOut->disable();
 149+ header("Content-Type: text/html");
 150+ header("Content-Disposition: attachment; filename=\"$book.html\"");
 151+ print $html;
 152+ }
 153+ else {
 154+ # Write the HTML to a tmp file
 155+ $file = "$wgUploadDirectory/".uniqid('pdf-book');
 156+ $fh = fopen($file, 'w+');
 157+ fwrite($fh, $html);
 158+ fclose($fh);
 159+
 160+ # Send the file to the client via htmldoc converter
 161+ $wgOut->disable();
 162+ header("Content-Type: application/pdf");
 163+ header("Content-Disposition: attachment; filename=\"$book.pdf\"");
 164+ $cmd = "--left $left --right $right --top $top --bottom $bottom";
 165+ $cmd .= " --header ... --footer .1. --headfootsize 8 --quiet --jpeg --color";
 166+ $cmd .= " --bodyfont $font --fontsize $size --linkstyle plain --linkcolor $links";
 167+ $cmd .= " --toclevels $levels --format pdf14 --numbered $layout";
 168+ $cmd = "htmldoc -t pdf --charset iso-8859-1 $cmd $file";
 169+ putenv("HTMLDOC_NOCGI=1");
 170+ passthru($cmd);
 171+ @unlink($file);
 172+ }
 173+ return false;
 174+ }
 175+
 176+ return true;
 177+ }
 178+
 179+ /**
 180+ * Return a property for htmldoc using global, request or passed default
 181+ */
 182+ function setProperty($name,$default) {
 183+ if (isset($_REQUEST["pdf$name"])) return $_REQUEST["pdf$name"];
 184+ if (isset($GLOBALS["wgPdfBook$name"])) return $GLOBALS["wgPdfBook$name"];
 185+ return $default;
 186+ }
 187+
 188+ /**
 189+ * Needed in some versions to prevent Special:Version from breaking
 190+ */
 191+ function __toString() { return 'PdfBook'; }
 192+}
 193+
 194+/**
 195+ * Called from $wgExtensionFunctions array when initialising extensions
 196+ */
 197+function wfSetupPdfBook() {
 198+ global $wgPdfBook;
 199+ $wgPdfBook = new PdfBook();
 200+}
 201+
 202+/**
 203+ * Needed in MediaWiki >1.8.0 for magic word hooks to work properly
 204+ */
 205+function wfPdfBookLanguageGetMagic(&$magicWords, $langCode = 0) {
 206+ global $wgPdfBookMagic;
 207+ $magicWords[$wgPdfBookMagic] = array($langCode, $wgPdfBookMagic);
 208+ return true;
 209+}
Property changes on: trunk/extensions/PdfBook/PdfBook.php
___________________________________________________________________
Added: svn:executable
1210 + *