4 This DB plugin allows to import PmWiki flat file databases. It is hard
5 to extend it as general backend, because that database format isn't all
6 too suiteable for ewiki (_BINARY entries are impossible with it and we
7 need random version access, not linear scan-through).
8 Importing goes by only reading a given sub database (it's always divided
9 into fragments). You eventually could access all by using "ext_subwiki"
10 and complicating the yoursite wrapper script (must extract PMWIKI_GROUP
11 from ?id= string much like PmWiki does itself).
13 In the _DIRS constant you define the paths to PmWikis wiki.d/ data
14 stores (there are typically two of them), where the first gets used
15 as active (writeable) directory.
20 define("SUBWIKI_SEPARATOR", ".");
21 define("PMWIKI_DB_DIRS", "../pmwiki/wiki.d/:../pmiki/wikilib.d/");
22 define("PMWIKI_GROUP", "Main");
26 $subwiki = $_REQUEST["group"];
28 $subwiki = PMWIKI_GROUP;
33 $ewiki_plugins["database"][0] = "ewiki_database_pmwiki";
37 class ewiki_database_pmwiki {
42 function ewiki_database_pmwiki ($dirs=PMWIKI_DB_DIRS, $group=PMWIKI_GROUP) {
43 $this->dirs = explode(":", $dirs);
44 $this->group = $group;
48 #-- retrieve/decode pages
49 function GET($id, $version=false) {
51 static $last_id, $last;
56 if ($id == $last_id) {
58 list($hash, $diffs, $other) = $last;
62 elseif ( ($fn = $this->FN($id)) && ($f = fopen($fn, "r")) )
68 #-- read line per line
69 $line = fgets($f, 1<<18); // 256K
70 if ($l = strpos($line, "=")) {
71 $field = trim(substr($line, 0, $l));
72 $line = rtrim(substr($line, $l+1), "\n");
81 if ($field == "newline") {
84 #-- old revision fields
85 elseif (strpos($field, ":")) {
86 list($fi,$n1,$n2,$n3) = explode(":", $field);
91 $other[$fi][$n1] = $line;
98 $hash["content"] = $line;
101 if ($l = strpos($line, ".")) {
102 $l = substr($line, $l+1);
107 $hash["lastmodified"] = $line;
110 if (empty($hash["author"])) {
111 $hash["author"] = $line;
114 $hash["author"] .= " ($line)";
118 if (empty($hash["author"])) {
119 $hash["author"] = $line;
122 $hash["author"] = $line . " ($hash[author])";
126 $hash["version"] = $line;
129 if ($field=="agent") {
130 $field = "user-agent";
132 $hash["meta"][$field] = $line;
140 $last = array($hash, $diffs, $other);
146 if ($hash["lastmodified"] && $hash["version"]) {
148 #-- guess missing information
149 $hash["created"] = filectime($fn);
150 $uu = array_flip(array_keys($diffs));
151 $last_diff_time = each($uu);
152 // $hash["created"] = $last_diff_time;
154 $hash["flags"] = EWIKI_DB_F_TEXT;
155 $hash["refs"] = "\n\n";
156 $hash["meta"] = (array)$hash["meta"];
158 #-- if prev version requested
159 if ($version && ($hash["version"] > $version)) {
161 #-- apply patches until it matches requested {version}
162 foreach ($diffs as $mtime=>$rpatch) {
163 if ($hash["version"] == $version) {
167 $hash["author"] = trim(
168 $others[$mtime]["author"] . ' ('.$others[$mtime]["host"].')'
170 $hash["content"] = $this->PATCH($hash["content"], $rpatch);
174 if ($version < $hash["version"]) {
189 function GETALL($fields, $mask=0, $filter=0) {
190 $r = new ewiki_dbquery_result($fields);
191 foreach ($this->LS() as $fn) {
192 if ($data = $this->GET($fn)) {
206 function FIND($list) {
209 foreach ($list as $id) {
210 $r[$id] = in_array($id, $ls);
216 #-- search for given filename
217 function FN($base_id) {
219 $dot = SUBWIKI_SEPARATOR;
220 foreach ($this->dirs as $dir) {
221 if (file_exists($fn = "$dir/$grp$dot$base_id")) {
227 #-- returns list of all existing files
229 $cmp = $this->group . SUBWIKI_SEPARATOR;
230 $ncmp = strlen($cmp);
232 foreach ($this->dirs as $dir) if ($dh = opendir($dir)) {
233 while ($fn = readdir($fn)) if (!is_dir($fn)) {
234 if (strncmp($fn, $cmp, $ncmp) == 0) {
235 $r[] = substr($fn, $ncmp);
243 #-- for decoding older versions
244 function PATCH($content, $rpatch) {
245 $f1 = EWIKI_TMP."/ewiki-pmwiki-db-import-".crc32($content)."-".time();
246 $f2 = $f1 . ".patch";
247 fwrite($f = fopen($f1, "w"), $content) && fclose($f);
248 fwrite($f = fopen($f2, "w"), $rpatch) && fclose($f);
250 $content = fread($f = fopen($f1, "r"), 1<<18); fclose($f);