bc8665197e4e53a201b59b4aa323afbdf110c749
[atutor.git] / mods / wiki / plugins / lib / sync.php
1 <?php
2 /*
3    This snippet implements the WikiSync(tm) utility functions and database
4    API (locally and for remote access).
5 */
6
7
8 #-- copy pages in one direction
9 function ewiki_sync_start($title, &$FROM_list, &$DEST_list, $FROM_api, $DEST_api) {
10    foreach ($FROM_list as $id=>$FROM_ver) {
11       set_time_limit(+2999);
12               
13       $DEST_ver = $DEST_list[$id];
14       if ($DEST_ver < $FROM_ver) {
15
16          echo "{$title}ing " . htmlentities($id) . "[{$FROM_ver}]... ";
17          $L = $FROM_api("::GET", array($id));
18
19          #-- did never exist,
20          #   or this version is identical on both systems
21          if (!$DEST_ver || ewiki_sync_no_conflict($id, $FROM_api, $DEST_api)) {
22             echo ($DEST_api("::WRITE", $L) ? "ok" : "error");
23          }
24          #-- conflict
25          else {
26             echo "<b>cannot</b> synchronize with [{$DEST_ver}] - conflict!";
27          }
28
29          echo "<br>\n";
30          flush();
31           
32          #-- no further processing with these entries
33          unset($FROM_list[$id]);
34          unset($DEST_list[$id]);
35       }
36       else {
37 #         echo "nothing to do for '$id' because $FROM_ver==$DEST_ver<br>\n";
38       }
39    }
40 }
41
42
43 #-- compare remote against local version for conflicts
44 function ewiki_sync_no_conflict($id, $OLD_api, $NEWER_api) {
45
46    #-- fetch
47    $OLD = $OLD_api("::GET", array($id));  // last
48    $NEW = $NEWER_api("::GET", array($id, $R["version"]));
49
50    #-- 700% identical!
51    if (md5(serialize($OLD)) == serialize(md5($NEW))) {
52       return true;
53    }
54    else {
55       return ewiki_sync_half_identical($OLD, $NEW);
56    }
57 }
58
59
60 #-- less exact comparison 
61 #   - it only skips the {hits} entry when matching fields,
62 #   because that's where differences are (huh, big secret!)
63 function ewiki_sync_half_identical($A, $B) {
64    
65    return
66      true
67      && (strtolower($A["id"]) == strtolower($B["id"]))
68      && ($A["flags"] == $B["flags"])
69      && ($A["version"] == $B["version"])
70      && ($A["lastmodified"] == $B["lastmodified"])
71      && (serialize($A["meta"]) == serialize($B["meta"]))
72
73        #-- you may wish to remove the following (two/???) :
74      && ($A["lastmodified"] == $B["lastmodified"])
75      && ($A["author"] == $B["author"])
76    ;  
77 }
78
79
80
81 #-- access to remotely located wikisync interface
82 function ewiki_sync_remote($func, $args=NULL) {
83    global $proto, $url;
84    if ($proto == "sync") {
85      switch (strtoupper(trim($func, ":"))) {
86         case "GET":
87            return phprpc($url, "ewiki.sync", array("::GET", $args));
88         case "WRITE":
89            return phprpc($url, "ewiki.sync", array("::WRITE", $args));
90         case "LIST":
91            return phprpc($url, "ewiki.sync", array("::LIST", false));
92         default:
93      }
94    }
95 }
96
97
98 #-- the public/main API, access local database
99 function ewiki_sync_local($func, $args=NULL) {
100    switch (strtoupper(trim($func, ":"))) {
101       case "GET":
102          return ewiki_db::GET($args[0], $args[1]);
103       case "WRITE":
104          return ewiki_db::WRITE($args);
105       case "LIST":
106          $all = ewiki_db::GETALL(array("id", "version"));
107          $r = array();
108          while ($row = $all->get()) {
109             $r[$row["id"]] = $row["version"];
110          }
111          return $r;
112       default:
113    }
114 }
115
116
117 ?>