Index: trunk/extensions/PdfBook/PdfBook.php |
— | — | @@ -18,9 +18,9 @@ |
19 | 19 | |
20 | 20 | define( 'PDFBOOK_VERSION', "1.0.9, 2010-12-17" ); |
21 | 21 | |
22 | | -$wgExtensionFunctions[] = 'wfSetupPdfBook'; |
23 | | -$wgHooks['LanguageGetMagic'][] = 'wfPdfBookLanguageGetMagic'; |
24 | | -$wgExtensionMessagesFiles['PdfBook'] = dirname( __FILE__ ) . '/PdfBook.i18n.php'; |
| 22 | +$dir = dirname( __FILE__ ); |
| 23 | +$wgAutoloadClasses['PdfBookHooks'] = $dir . '/PdfBook.hooks.php'; |
| 24 | +$wgExtensionMessagesFiles['PdfBook'] = $dir . '/PdfBook.i18n.php'; |
25 | 25 | |
26 | 26 | $wgExtensionCredits['parserhook'][] = array( |
27 | 27 | 'path' => __FILE__, |
— | — | @@ -32,209 +32,16 @@ |
33 | 33 | ); |
34 | 34 | |
35 | 35 | # Whether or not an action tab is wanted for printing to PDF |
36 | | -if( !isset( $wgPdfBookTab ) ) $wgPdfBookTab = false; |
| 36 | +$wgPdfBookTab = false; |
37 | 37 | |
38 | | -class PdfBook { |
| 38 | +$wgHooks['UnknownAction'][] = 'PdfBookHooks::onUnknownAction'; |
39 | 39 | |
40 | | - function __construct() { |
41 | | - global $wgHooks, $wgParser, $wgPdfBookMagic; |
42 | | - global $wgLogTypes, $wgLogNames, $wgLogHeaders, $wgLogActions, $wgPdfBookTab; |
43 | | - $wgHooks['UnknownAction'][] = $this; |
| 40 | +# Hooks for pre-Vector and Vector addtabs. |
| 41 | +$wgHooks['SkinTemplateTabs'][] = 'PdfBookHooks::onSkinTemplateTabs'; |
| 42 | +$wgHooks['SkinTemplateNavigation'][] = 'PdfBookHooks::onSkinTemplateNavigation'; |
44 | 43 | |
45 | | - # Hooks for pre-Vector and Vector addtabs. |
46 | | - if( $wgPdfBookTab ) { |
47 | | - $wgHooks['SkinTemplateTabs'][] = $this ; |
48 | | - $wgHooks['SkinTemplateNavigation'][] = $this; |
49 | | - } |
50 | | - |
51 | | - # Add a new pdf log type |
52 | | - $wgLogTypes[] = 'pdf'; |
53 | | - $wgLogNames ['pdf'] = 'pdflogpage'; |
54 | | - $wgLogHeaders['pdf'] = 'pdflogpagetext'; |
55 | | - $wgLogActions['pdf/book'] = 'pdflogentry'; |
56 | | - |
57 | | - } |
58 | | - |
59 | | - |
60 | | - /** |
61 | | - * Perform the export operation |
62 | | - */ |
63 | | - function onUnknownAction( $action, $article ) { |
64 | | - global $wgOut, $wgUser, $wgTitle, $wgParser, $wgRequest; |
65 | | - global $wgServer, $wgArticlePath, $wgScriptPath, $wgUploadPath, $wgUploadDirectory, $wgScript; |
66 | | - |
67 | | - if( $action == 'pdfbook' ) { |
68 | | - |
69 | | - $title = $article->getTitle(); |
70 | | - $opt = ParserOptions::newFromUser( $wgUser ); |
71 | | - |
72 | | - # Log the export |
73 | | - $msg = wfMsg( 'pdfbook-log', $wgUser->getUserPage()->getPrefixedText() ); |
74 | | - $log = new LogPage( 'pdf', false ); |
75 | | - $log->addEntry( 'book', $wgTitle, $msg ); |
76 | | - |
77 | | - # Initialise PDF variables |
78 | | - $format = $wgRequest->getText( 'format' ); |
79 | | - $notitle = $wgRequest->getText( 'notitle' ); |
80 | | - $layout = $format == 'single' ? '--webpage' : '--firstpage toc'; |
81 | | - $charset = $this->setProperty( 'Charset', 'iso-8859-1' ); |
82 | | - $left = $this->setProperty( 'LeftMargin', '1cm' ); |
83 | | - $right = $this->setProperty( 'RightMargin', '1cm' ); |
84 | | - $top = $this->setProperty( 'TopMargin', '1cm' ); |
85 | | - $bottom = $this->setProperty( 'BottomMargin','1cm' ); |
86 | | - $font = $this->setProperty( 'Font', 'Arial' ); |
87 | | - $size = $this->setProperty( 'FontSize', '8' ); |
88 | | - $ls = $this->setProperty( 'LineSpacing', 1 ); |
89 | | - $linkcol = $this->setProperty( 'LinkColour', '217A28' ); |
90 | | - $levels = $this->setProperty( 'TocLevels', '2' ); |
91 | | - $exclude = $this->setProperty( 'Exclude', array() ); |
92 | | - $width = $this->setProperty( 'Width', '' ); |
93 | | - $width = $width ? "--browserwidth $width" : ''; |
94 | | - if( !is_array( $exclude ) ) $exclude = split( '\\s*,\\s*', $exclude ); |
95 | | - |
96 | | - # Select articles from members if a category or links in content if not |
97 | | - if( $format == 'single' ) $articles = array( $title ); |
98 | | - else { |
99 | | - $articles = array(); |
100 | | - if( $title->getNamespace() == NS_CATEGORY ) { |
101 | | - $db = wfGetDB( DB_SLAVE ); |
102 | | - $cat = $db->addQuotes( $title->getDBkey() ); |
103 | | - $result = $db->select( |
104 | | - 'categorylinks', |
105 | | - 'cl_from', |
106 | | - "cl_to = $cat", |
107 | | - 'PdfBook', |
108 | | - array( 'ORDER BY' => 'cl_sortkey' ) |
109 | | - ); |
110 | | - if( $result instanceof ResultWrapper ) $result = $result->result; |
111 | | - while ( $row = $db->fetchRow( $result ) ) $articles[] = Title::newFromID( $row[0] ); |
112 | | - } |
113 | | - else { |
114 | | - $text = $article->fetchContent(); |
115 | | - $text = $wgParser->preprocess( $text, $title, $opt ); |
116 | | - if ( preg_match_all( "/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m", $text, $links ) ) |
117 | | - foreach ( $links[1] as $link ) $articles[] = Title::newFromText( $link ); |
118 | | - } |
119 | | - } |
120 | | - |
121 | | - # Format the article(s) as a single HTML document with absolute URL's |
122 | | - $book = $title->getText(); |
123 | | - $html = ''; |
124 | | - $wgArticlePath = $wgServer.$wgArticlePath; |
125 | | - $wgPdfBookTab = false; |
126 | | - $wgScriptPath = $wgServer.$wgScriptPath; |
127 | | - $wgUploadPath = $wgServer.$wgUploadPath; |
128 | | - $wgScript = $wgServer.$wgScript; |
129 | | - foreach( $articles as $title ) { |
130 | | - $ttext = $title->getPrefixedText(); |
131 | | - if( !in_array( $ttext, $exclude ) ) { |
132 | | - $article = new Article( $title ); |
133 | | - $text = $article->fetchContent(); |
134 | | - $text = preg_replace( "/<!--([^@]+?)-->/s", "@@" . "@@$1@@" . "@@", $text ); # preserve HTML comments |
135 | | - if( $format != 'single' ) $text .= "__NOTOC__"; |
136 | | - $opt->setEditSection( false ); # remove section-edit links |
137 | | - $out = $wgParser->parse( $text, $title, $opt, true, true ); |
138 | | - $text = $out->getText(); |
139 | | - $text = preg_replace( "|(<img[^>]+?src=\")(/.+?>)|", "$1$wgServer$2", $text ); # make image urls absolute |
140 | | - $text = preg_replace( "|<div\s*class=['\"]?noprint[\"']?>.+?</div>|s", "", $text ); # non-printable areas |
141 | | - $text = preg_replace( "|@{4}([^@]+?)@{4}|s", "<!--$1-->", $text ); # HTML comments hack |
142 | | - $ttext = basename( $ttext ); |
143 | | - $h1 = $notitle ? "" : "<center><h1>$ttext</h1></center>"; |
144 | | - $html .= utf8_decode( "$h1$text\n" ); |
145 | | - } |
146 | | - } |
147 | | - |
148 | | - # $wgPdfBookTab = false; If format=html in query-string, return html content directly |
149 | | - if( $format == 'html' ) { |
150 | | - $wgOut->disable(); |
151 | | - header( "Content-Type: text/html" ); |
152 | | - header( "Content-Disposition: attachment; filename=\"$book.html\"" ); |
153 | | - print $html; |
154 | | - } |
155 | | - else { |
156 | | - # Write the HTML to a tmp file |
157 | | - $file = "$wgUploadDirectory/" . uniqid( 'pdf-book' ); |
158 | | - $fh = fopen( $file, 'w+' ); |
159 | | - fwrite( $fh, $html ); |
160 | | - fclose( $fh ); |
161 | | - |
162 | | - $footer = $format == 'single' ? "..." : ".1."; |
163 | | - $toc = $format == 'single' ? "" : " --toclevels $levels"; |
164 | | - |
165 | | - # Send the file to the client via htmldoc converter |
166 | | - $wgOut->disable(); |
167 | | - header( "Content-Type: application/pdf" ); |
168 | | - header( "Content-Disposition: attachment; filename=\"$book.pdf\"" ); |
169 | | - $cmd = "--left $left --right $right --top $top --bottom $bottom"; |
170 | | - $cmd .= " --header ... --footer $footer --headfootsize 8 --quiet --jpeg --color"; |
171 | | - $cmd .= " --bodyfont $font --fontsize $size --fontspacing $ls --linkstyle plain --linkcolor $linkcol"; |
172 | | - $cmd .= "$toc --no-title --format pdf14 --numbered $layout $width"; |
173 | | - $cmd = "htmldoc -t pdf --charset $charset $cmd $file"; |
174 | | - putenv( "HTMLDOC_NOCGI=1" ); |
175 | | - passthru( $cmd ); |
176 | | - @unlink( $file ); |
177 | | - } |
178 | | - return false; |
179 | | - } |
180 | | - |
181 | | - return true; |
182 | | - } |
183 | | - |
184 | | - |
185 | | - /** |
186 | | - * Return a property for htmldoc using global, request or passed default |
187 | | - */ |
188 | | - function setProperty( $name, $default ) { |
189 | | - global $wgRequest; |
190 | | - if ( $wgRequest->getText( "pdf$name" ) ) return $wgRequest->getText( "pdf$name" ); |
191 | | - if ( isset( $GLOBALS["wgPdfBook$name"] ) ) return $GLOBALS["wgPdfBook$name"]; |
192 | | - return $default; |
193 | | - } |
194 | | - |
195 | | - |
196 | | - /** |
197 | | - * Add PDF to actions tabs in MonoBook based skins |
198 | | - */ |
199 | | - function onSkinTemplateTabs( $skin, &$actions) { |
200 | | - global $wgTitle; |
201 | | - $actions['pdfbook'] = array( |
202 | | - 'class' => false, |
203 | | - 'text' => wfMsg( 'pdfbook-action' ), |
204 | | - 'href' => $wgTitle->getLocalURL( "action=pdfbook&format=single" ), |
205 | | - ); |
206 | | - return true; |
207 | | - } |
208 | | - |
209 | | - |
210 | | - /** |
211 | | - * Add PDF to actions tabs in vector based skins |
212 | | - */ |
213 | | - function onSkinTemplateNavigation( $skin, &$actions ) { |
214 | | - global $wgTitle; |
215 | | - $actions['views']['pdfbook'] = array( |
216 | | - 'class' => false, |
217 | | - 'text' => wfMsg( 'pdfbook-action' ), |
218 | | - 'href' => $wgTitle->getLocalURL( "action=pdfbook&format=single" ), |
219 | | - ); |
220 | | - return true; |
221 | | - } |
222 | | -} |
223 | | - |
224 | | - |
225 | | -/** |
226 | | - * Called from $wgExtensionFunctions array when initialising extensions |
227 | | - */ |
228 | | -function wfSetupPdfBook() { |
229 | | - global $wgPdfBook; |
230 | | - $wgPdfBook = new PdfBook(); |
231 | | -} |
232 | | - |
233 | | - |
234 | | -/** |
235 | | - * Needed in MediaWiki >1.8.0 for magic word hooks to work properly |
236 | | - */ |
237 | | -function wfPdfBookLanguageGetMagic( &$magicWords, $langCode = 0 ) { |
238 | | - global $wgPdfBookMagic; |
239 | | - $magicWords[$wgPdfBookMagic] = array( $langCode, $wgPdfBookMagic ); |
240 | | - return true; |
241 | | -} |
| 44 | +# Add a new pdf log type |
| 45 | +$wgLogTypes[] = 'pdf'; |
| 46 | +$wgLogNames ['pdf'] = 'pdflogpage'; |
| 47 | +$wgLogHeaders['pdf'] = 'pdflogpagetext'; |
| 48 | +$wgLogActions['pdf/book'] = 'pdflogentry'; |
Index: trunk/extensions/PdfBook/PdfBook.hooks.php |
— | — | @@ -0,0 +1,173 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class PdfBookHooks { |
| 5 | + |
| 6 | + /** |
| 7 | + * Perform the export operation |
| 8 | + */ |
| 9 | + public static function onUnknownAction( $action, $article ) { |
| 10 | + global $wgOut, $wgUser, $wgParser, $wgRequest; |
| 11 | + global $wgServer, $wgArticlePath, $wgScriptPath, $wgUploadPath, $wgUploadDirectory, $wgScript; |
| 12 | + |
| 13 | + if( $action == 'pdfbook' ) { |
| 14 | + |
| 15 | + $title = $article->getTitle(); |
| 16 | + $opt = ParserOptions::newFromUser( $wgUser ); |
| 17 | + |
| 18 | + # Log the export |
| 19 | + $msg = wfMsg( 'pdfbook-log', $wgUser->getUserPage()->getPrefixedText() ); |
| 20 | + $log = new LogPage( 'pdf', false ); |
| 21 | + $log->addEntry( 'book', $article->getTitle(), $msg ); |
| 22 | + |
| 23 | + # Initialise PDF variables |
| 24 | + $format = $wgRequest->getText( 'format' ); |
| 25 | + $notitle = $wgRequest->getText( 'notitle' ); |
| 26 | + $layout = $format == 'single' ? '--webpage' : '--firstpage toc'; |
| 27 | + $charset = self::setProperty( 'Charset', 'iso-8859-1' ); |
| 28 | + $left = self::setProperty( 'LeftMargin', '1cm' ); |
| 29 | + $right = self::setProperty( 'RightMargin', '1cm' ); |
| 30 | + $top = self::setProperty( 'TopMargin', '1cm' ); |
| 31 | + $bottom = self::setProperty( 'BottomMargin','1cm' ); |
| 32 | + $font = self::setProperty( 'Font', 'Arial' ); |
| 33 | + $size = self::setProperty( 'FontSize', '8' ); |
| 34 | + $ls = self::setProperty( 'LineSpacing', 1 ); |
| 35 | + $linkcol = self::setProperty( 'LinkColour', '217A28' ); |
| 36 | + $levels = self::setProperty( 'TocLevels', '2' ); |
| 37 | + $exclude = self::setProperty( 'Exclude', array() ); |
| 38 | + $width = self::setProperty( 'Width', '' ); |
| 39 | + $width = $width ? "--browserwidth $width" : ''; |
| 40 | + if( !is_array( $exclude ) ) $exclude = split( '\\s*,\\s*', $exclude ); |
| 41 | + |
| 42 | + # Select articles from members if a category or links in content if not |
| 43 | + if( $format == 'single' ) $articles = array( $title ); |
| 44 | + else { |
| 45 | + $articles = array(); |
| 46 | + if( $title->getNamespace() == NS_CATEGORY ) { |
| 47 | + $db = wfGetDB( DB_SLAVE ); |
| 48 | + $cat = $db->addQuotes( $title->getDBkey() ); |
| 49 | + $result = $db->select( |
| 50 | + 'categorylinks', |
| 51 | + 'cl_from', |
| 52 | + "cl_to = $cat", |
| 53 | + 'PdfBook', |
| 54 | + array( 'ORDER BY' => 'cl_sortkey' ) |
| 55 | + ); |
| 56 | + if( $result instanceof ResultWrapper ) $result = $result->result; |
| 57 | + while ( $row = $db->fetchRow( $result ) ) $articles[] = Title::newFromID( $row[0] ); |
| 58 | + } |
| 59 | + else { |
| 60 | + $text = $article->fetchContent(); |
| 61 | + $text = $wgParser->preprocess( $text, $title, $opt ); |
| 62 | + if ( preg_match_all( "/^\\*\\s*\\[{2}\\s*([^\\|\\]]+)\\s*.*?\\]{2}/m", $text, $links ) ) |
| 63 | + foreach ( $links[1] as $link ) $articles[] = Title::newFromText( $link ); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + # Format the article(s) as a single HTML document with absolute URL's |
| 68 | + $book = $title->getText(); |
| 69 | + $html = ''; |
| 70 | + $wgArticlePath = $wgServer.$wgArticlePath; |
| 71 | + $wgPdfBookTab = false; |
| 72 | + $wgScriptPath = $wgServer.$wgScriptPath; |
| 73 | + $wgUploadPath = $wgServer.$wgUploadPath; |
| 74 | + $wgScript = $wgServer.$wgScript; |
| 75 | + foreach( $articles as $title ) { |
| 76 | + $ttext = $title->getPrefixedText(); |
| 77 | + if( !in_array( $ttext, $exclude ) ) { |
| 78 | + $article = new Article( $title ); |
| 79 | + $text = $article->fetchContent(); |
| 80 | + $text = preg_replace( "/<!--([^@]+?)-->/s", "@@" . "@@$1@@" . "@@", $text ); # preserve HTML comments |
| 81 | + if( $format != 'single' ) $text .= "__NOTOC__"; |
| 82 | + $opt->setEditSection( false ); # remove section-edit links |
| 83 | + $out = $wgParser->parse( $text, $title, $opt, true, true ); |
| 84 | + $text = $out->getText(); |
| 85 | + $text = preg_replace( "|(<img[^>]+?src=\")(/.+?>)|", "$1$wgServer$2", $text ); # make image urls absolute |
| 86 | + $text = preg_replace( "|<div\s*class=['\"]?noprint[\"']?>.+?</div>|s", "", $text ); # non-printable areas |
| 87 | + $text = preg_replace( "|@{4}([^@]+?)@{4}|s", "<!--$1-->", $text ); # HTML comments hack |
| 88 | + $ttext = basename( $ttext ); |
| 89 | + $h1 = $notitle ? "" : "<center><h1>$ttext</h1></center>"; |
| 90 | + $html .= utf8_decode( "$h1$text\n" ); |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + # $wgPdfBookTab = false; If format=html in query-string, return html content directly |
| 95 | + if( $format == 'html' ) { |
| 96 | + $wgOut->disable(); |
| 97 | + header( "Content-Type: text/html" ); |
| 98 | + header( "Content-Disposition: attachment; filename=\"$book.html\"" ); |
| 99 | + print $html; |
| 100 | + } |
| 101 | + else { |
| 102 | + # Write the HTML to a tmp file |
| 103 | + $file = "$wgUploadDirectory/" . uniqid( 'pdf-book' ); |
| 104 | + $fh = fopen( $file, 'w+' ); |
| 105 | + fwrite( $fh, $html ); |
| 106 | + fclose( $fh ); |
| 107 | + |
| 108 | + $footer = $format == 'single' ? "..." : ".1."; |
| 109 | + $toc = $format == 'single' ? "" : " --toclevels $levels"; |
| 110 | + |
| 111 | + # Send the file to the client via htmldoc converter |
| 112 | + $wgOut->disable(); |
| 113 | + header( "Content-Type: application/pdf" ); |
| 114 | + header( "Content-Disposition: attachment; filename=\"$book.pdf\"" ); |
| 115 | + $cmd = "--left $left --right $right --top $top --bottom $bottom"; |
| 116 | + $cmd .= " --header ... --footer $footer --headfootsize 8 --quiet --jpeg --color"; |
| 117 | + $cmd .= " --bodyfont $font --fontsize $size --fontspacing $ls --linkstyle plain --linkcolor $linkcol"; |
| 118 | + $cmd .= "$toc --no-title --format pdf14 --numbered $layout $width"; |
| 119 | + $cmd = "htmldoc -t pdf --charset $charset $cmd $file"; |
| 120 | + putenv( "HTMLDOC_NOCGI=1" ); |
| 121 | + passthru( $cmd ); |
| 122 | + @unlink( $file ); |
| 123 | + } |
| 124 | + return false; |
| 125 | + } |
| 126 | + |
| 127 | + return true; |
| 128 | + } |
| 129 | + |
| 130 | + |
| 131 | + /** |
| 132 | + * Return a property for htmldoc using global, request or passed default |
| 133 | + */ |
| 134 | + private static function setProperty( $name, $default ) { |
| 135 | + global $wgRequest; |
| 136 | + if ( $wgRequest->getText( "pdf$name" ) ) return $wgRequest->getText( "pdf$name" ); |
| 137 | + if ( isset( $GLOBALS["wgPdfBook$name"] ) ) return $GLOBALS["wgPdfBook$name"]; |
| 138 | + return $default; |
| 139 | + } |
| 140 | + |
| 141 | + |
| 142 | + /** |
| 143 | + * Add PDF to actions tabs in MonoBook based skins |
| 144 | + */ |
| 145 | + public static function onSkinTemplateTabs( $skin, &$actions) { |
| 146 | + global $wgPdfBookTab; |
| 147 | + |
| 148 | + if ( $wgPdfBookTab ) { |
| 149 | + $actions['pdfbook'] = array( |
| 150 | + 'class' => false, |
| 151 | + 'text' => wfMsg( 'pdfbook-action' ), |
| 152 | + 'href' => $skin->getTitle()->getLocalURL( "action=pdfbook&format=single" ), |
| 153 | + ); |
| 154 | + } |
| 155 | + return true; |
| 156 | + } |
| 157 | + |
| 158 | + |
| 159 | + /** |
| 160 | + * Add PDF to actions tabs in vector based skins |
| 161 | + */ |
| 162 | + public static function onSkinTemplateNavigation( $skin, &$actions ) { |
| 163 | + global $wgPdfBookTab; |
| 164 | + |
| 165 | + if ( $wgPdfBookTab ) { |
| 166 | + $actions['views']['pdfbook'] = array( |
| 167 | + 'class' => false, |
| 168 | + 'text' => wfMsg( 'pdfbook-action' ), |
| 169 | + 'href' => $skin->getTitle()->getLocalURL( "action=pdfbook&format=single" ), |
| 170 | + ); |
| 171 | + } |
| 172 | + return true; |
| 173 | + } |
| 174 | +} |
Property changes on: trunk/extensions/PdfBook/PdfBook.hooks.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 175 | + native |