4cf73ee4a8a1a8e8c42927ea862426ac34f9bc9b
[atutor.git] / mods / wiki / plugins / page / wikidump.php
1 <?php
2
3 /*
4    Allows to download a tarball including all WikiPages and images that
5    currently are in the database.
6 */
7
8
9 #-- text
10 $ewiki_t["en"]["WIKIDUMP"] = "Here you can download all pages of this Wiki in HTML format at once. They'll get packed into a an archive of the UNIX .tar format.";
11 $ewiki_t["en"]["download tarball"] = "Download Tarball";
12 $ewiki_t["en"]["with images"] = "With images";
13 $ewiki_t["en"]["complete .html files"] = "Complete HTMLfiles";
14 $ewiki_t["en"]["include virtual pages"] = "Include virtual pages";
15
16 $ewiki_t["de"]["WIKIDUMP"] = "Du kannst dir hier alle Seiten des Wikis im HTML-Format herunterladen. Das Archiv wird im UNIX .tar Format erstellt.";
17 $ewiki_t["de"]["download tarball"] = "tarball herunterladen";
18 $ewiki_t["de"]["with images"] = "mit Graphiken";
19 $ewiki_t["de"]["complete .html files"] = "vollständige .html Dateien";
20 $ewiki_t["de"]["include virtual pages"] = "auch virtuelle Seiten";
21
22 #-- glue
23 $ewiki_plugins["page"]["WikiDump"] = "ewiki_page_wiki_dump_tarball";
24
25
26
27 #-- template (if $fullhtml)
28 function ewiki_dump_template($id, $content, $linksto=0, $html_ext=".html") {
29
30    $title = $head_title = ewiki_split_title($id);
31    if ($linksto != 0) {
32       $title = '<a href="' . urlencode(urlencode($id)). (($linksto>0) ? '.links':''). $html_ext . '">' . $title . '</a>';
33    }
34    $version = EWIKI_VERSION;
35
36    return <<<EOT
37 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
38 <html>
39 <head>
40  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
41  <title>$head_title</title>
42  <meta name="generator" content="WikiDump, ewiki/$version">
43 </head>
44 <body bgcolor="#ffffff";>
45 <h2>$title</h2>
46 $content
47 </body>
48 </html>
49 EOT;
50 }
51
52
53
54 function ewiki_page_wiki_dump_tarball($id, $data, $action) {
55
56    #-- return legacy page
57    if (empty($_REQUEST["download_tarball"])) {
58       $url = ewiki_script("", $id);
59       return(ewiki_make_title($id, $id, 2) . ewiki_t(<<<END
60 _{WIKIDUMP}
61 <br /><br />
62 <form action="$url" method="POST" enctype="multipart/form-data">
63 <input type="hidden" name="id" value="$id">
64 <input type="submit" name="download_tarball" value="_{download tarball}">
65 <br /><br />
66 <input type="checkbox" name="dump_images" value="1"> _{with images}<br />
67 <input type="checkbox" name="dump_virtual" value="1"> _{include virtual pages}<br />
68 <input type="checkbox" name="dump_fullhtml" value="1" checked> _{complete .html files}<br />
69 &nbsp; &nbsp; &nbsp; <input type="checkbox" name="dump_linksto" value="1"> _{with backlink pages}<br />
70 </form>
71 END
72       ));
73    }
74    #-- tarball generation
75    else {
76       $di = $_REQUEST["dump_images"];
77       $fh = $_REQUEST["dump_fullhtml"];
78       $bl = $_REQUEST["dump_linksto"];
79       $vp = $_REQUEST["dump_virtual"];
80       $_REQUEST = $_GET = $_POST = array();
81       set_time_limit(180);
82       ewiki_page_wiki_dump_send($di, $fh, $vp, $bl);
83    }
84 }
85
86
87 function ewiki_page_wiki_dump_send($imgs=1, $fullhtml=0, $virtual=0, $linksto=0) {
88
89    global $ewiki_config, $ewiki_plugins;
90
91    #-- reconfigure ewiki_format() to generate offline pages and files
92    $html_ext = ".htm";
93    if ($fullhtml) {
94       $html_ext = ".html";
95    }
96    $ewiki_config["script"] = "%s$html_ext";
97    $ewiki_config["script_binary"] = "%s";
98    $ewiki_config["print_title"] = 0;
99
100    #-- fetch also dynamic pages
101    if ($virtual) {
102       $virtual = array_keys($ewiki_plugins["page"]);
103    } else {
104       $virtual = array();
105    }
106
107
108    #-- get all pages / binary files
109    $result = ewiki_db::GETALL(array("id", "version", "flags"));
110    if ($result) {
111
112       #-- HTTP headers
113       header("Content-Type: application/x-tar");
114       header("Content-Disposition: attachment; filename=\"WikiDump.tar.gz\"");
115
116       #-- start tar file
117       $tarball = new ewiki_virtual_tarball();
118       $tarball->open(0);
119
120       #-- convert all pages
121       while (($row=$result->get()) || count($virtual)) {
122
123          $content = "";
124
125          #-- fetch page from database
126          if ($id = $row["id"]) {
127             $row = ewiki_db::GET($id);
128          }
129          #-- virtual page plugins
130          elseif ($id = array_pop($virtual)) {
131             $pf = $ewiki_plugins["page"][$id];
132             $content = $pf($id, $content, "view");
133             $row = array(
134                "flags" => EWIKI_DB_F_TEXT|EWIKI_DB_F_HTML,
135                "lastmodified" => time(),
136             );
137          }
138          else {
139             break;
140          }
141
142          #-- file name
143          $fn = $id;
144          $fn = urlencode($fn);
145
146          #-- post process for ordinary pages / binary data
147          if (empty($content))
148          switch ($row["flags"] & EWIKI_DB_F_TYPE) {
149
150             case (EWIKI_DB_F_TEXT):
151                $content = ewiki_format($row["content"]);
152                break;
153
154             case (EWIKI_DB_F_BINARY):
155                if (($row["meta"]["class"]=="image") && ($imgs)) {
156                   $content = &$row["content"];
157                }
158                else {
159                   return;
160                }
161                break;
162
163             default:
164                # don't want it
165                continue;
166          }
167
168          #-- size check
169          if (empty($content)) {
170             continue;
171          }
172
173          #-- for tarball
174          $perms = array(
175             "mtime" => $row["lastmodified"],
176             "uname" => "ewiki",
177             "mode" => 0664 | (($row["flags"]&EWIKI_DB_F_WRITEABLE)?0002:0000),
178          );
179
180          #-- html post process
181          if (!($row["flags"] & EWIKI_DB_F_BINARY)) {
182
183             #-- use page template
184             if ($fullhtml) {
185                $content = ewiki_dump_template($id, $content, $linksto);
186             }
187
188             #-- add links/ page
189             if ($linksto) {
190                $tarball->add(
191                   "$fn.links$html_ext",
192                   ewiki_dump_template(
193                      $id,
194                      ewiki_page_links($id, $row, "links"),
195                      $lto=-1
196                   ),
197                   $perms
198                );
199             }
200
201             $fn .= $html_ext;
202          }
203
204          #-- add file
205          $tarball->add(
206             $fn,
207             $content,
208             $perms
209          );
210       }
211
212       #-- end output
213       $tarball->close();
214
215    }
216
217    #-- fin 
218    die();
219 }
220
221
222
223
224 ############################################################################
225
226
227
228
229 #-- allows to generate a tarball from virtual files
230 #   (supports no directories or symlinks and other stuff)
231 class ewiki_virtual_tarball {
232
233    var $f = 0;
234
235    function open($fn="/dev/stdout") {
236
237       #-- init;
238       $this->f = 0;
239
240       #-- file output?
241       if ($fn && ($fn != "-")) {
242          $this->f = gzopen("$fn", "wb9");
243       }
244       else {
245          $_ENV["HTTP_ACCEPT_ENCODING"] = "gzip, deflate";
246          $_SERVER["HTTP_ACCEPT_ENCODING"] = "gzip, deflate";
247          ob_start("ob_gzhandler");
248       }
249    }
250
251
252    function close() {
253
254       #-- fill up file
255       $this->write(str_repeat("\000", 9*1024));
256
257       #-- close file handle
258       if ($this->f) {
259          gzclose($this->f);
260       }
261    }
262
263
264    function write($str) {
265       if ($this->f) {
266          gzwrite($this->f, $str);
267          fflush($this->f);
268       }
269       else {
270          echo $str;
271          ob_flush();
272       }
273    }
274
275
276    function oct($int, $len) {
277       $o = "\000";
278       while (--$len) {
279          $o = ($int & 0x07) . $o;
280          $int = $int >> 3;
281       }
282       return($o);
283    }
284
285
286    #-- add virtual file
287    function add($filename, $content, $args=array()) {
288
289       $args = array_merge($args, array(
290          "mode" => 000664,
291          "mtime" => time(),
292          "ctime" => time(),
293          "uid" => 65534,       #-- common for user "nobody"
294          "gid" => 65534,
295          "uname" => "nobody",
296          "gname" => "nobody",
297          "type" => "0",
298       ));
299       $args["mode"] |= 0100000;
300       $args["size"] = strlen($content);
301       $checksum = "        ";
302       $magic = "ustar  \000";
303       $filename = substr($filename, 0, 99);
304
305       #-- header record
306       $header  = str_pad($filename, 100, "\000")            # 0x0000
307                . $this->oct($args["mode"], 8)               # 0x0064
308                . $this->oct($args["uid"], 8)                # 0x006C
309                . $this->oct($args["gid"], 8)                # 0x0074
310                . $this->oct($args["size"], 12)              # 0x007C
311                . $this->oct($args["mtime"], 12)             # 0x0088
312                . ($checksum)                                # 0x0094
313                . ($args["type"])                            # 0x009C
314                . str_repeat("\000", 100)                    # 0x009D
315                . ($magic)                                   # 0x0101
316                . str_pad($args["uname"], 32, "\000")        # 0x0109
317                . str_pad($args["gname"], 32, "\000")        # 0x0129
318                ;                                            # 0x0149
319       $header = str_pad($header, 512, "\000");
320
321       #-- calculate and add header checksum
322       $cksum = 0;
323       for ($n=0; $n<512; $n++) {
324          $cksum += ord($header[$n]);
325       }
326       $header = substr($header, 0, 0x0094)
327               . $this->oct($cksum, 7) . " "
328               . substr($header, 0x009C);
329
330       #-- output
331       if ($fill = (512 - (strlen($content) % 512))) {
332          $content .= str_repeat("\000", $fill);
333       }
334       $this->write($header . $content);
335    }
336
337
338 }
339
340
341
342 ?>