3 WebDAV provides authoring and file access features via HTTP (it is
4 in fact an extension to it). This fits very well with Wiki, and a
5 nice client assumed provides another useful page editing interface.
7 This snippet is innovocated by "z.php", and itself depends upon a
8 modified version of the HTTP_WebDAV_Server module (originally PEAR).
9 It does not yet work together with _PROTECTED_MODE settings, that's
10 why "fragments/funcs/auth.php" should be used meanwhile (as always),
11 even if the WebDAV standard actually forbidds to use the Basic auth
12 mechanism (most implementations ignore this stupid rule, and as it
13 is AntiWiki we ignore it even harder).
15 Because ewiki has a really flat namespace (despite of subpages, we
16 don't have PageGroups or SubWikis fired up per default), and even
17 pagenames with a slash inside won't be treated as directories in
18 any case. That's why the implementation of our WebDAV interface is
19 much shorter than for other systems.
22 - likely to work with Wiki pages only (handling of _BINARY entries
24 - enriched with content-coding (compression) support, though it'll
25 only work for GET and PUT (won't patch the WebDAV class), but
26 todays WebDAV clients are plain stupid in this regard anyhow
27 - use the "plugins/debug/xerror.php" script together with this, if
28 you'd like to see error messages (for debugging)
33 define("EWIKI_SCRIPT_WEBDAV", EWIKI_BASE_URL . "z.php/"); // may be we should use a separate z_dav.php script or so?
34 define("EWIKI_PAGE_CTYPE", "text/wiki; variant=ewiki; charset=iso-8859-1");
35 $ewiki_config["ua"] .= " WebDav/0.0.3";
36 define("WEBDAV_DIR_DEPTH", 1); // make 0 to always include files from a collection
40 class WikiDav extends MiniDav
47 $this->int_charset = strtolower(EWIKI_CHARSET); // L1 only!
48 if (!function_exists("ewiki_http_header_errors") && !function_exists("ewiki_xml_comment_errors")) {
51 $this->xmlns["page"] = "urn:x-ewiki:db:page-data";
52 $this->xmlns["meta"] = "urn:x-ewiki:db:meta-meta";
60 #-- page name, look it up in database
61 $id = $this->id($path);
63 $data = ewiki_db::GET($id, $version);
66 if ($id && $data && $data["version"]) {
69 ewiki_http_headers($data["content"], $id, $data, "view", $_saveasfn=0);
72 return $this->GET_response($data["content"], $data["lastmodified"], EWIKI_PAGE_CTYPE);
76 return "404 Not Found";
82 #-- get meta data of page
83 function PROPFIND($path, $props) {
86 $id = $this->id($path);
90 if (!strlen($id) || ($id=="/")) {
92 $oldest_time = 2*UNIX_MILLENNIUM;
93 $result = ewiki_db::GETALL(array());
94 while ($data = $result->get(1, 0x137f)) {
95 if ($this->depth >= WEBDAV_DIR_DEPTH) {
96 $files[] = $this->fileinfo($data);
98 $oldest_time = min($oldest_time, $data["created"]);
101 #-- add entry for virtual root directory
104 "created"=>$oldest_time,
106 $files[] = $this->dirinfo($data);
109 #-- just the specified one
112 $data = ewiki_db::GET($id, $version);
114 $files[] = $this->fileinfo($data);
124 #-- rearrange page meta data fields as array for WebDAV class
125 function fileinfo(&$data) {
127 #-- create meta/properties array
128 ($ct = $data["meta"]["Content-Type"]) or ($ct = EWIKI_PAGE_CTYPE);
130 "path" => "/" . $data["id"], // yes just a slash, no _SCRIPT_WEBDAV prefix
131 "resourcetype" => "", // "" ordinary page, was "collection" for dirs
132 "creationdate" => $data["created"],
133 "getcontentlength" => strlen($data["content"]),
134 "getlastmodified" => $data["lastmodified"],
135 "getcontenttype" => $ct,
136 "displayname" => ewiki_split_title($data["id"]),
137 "getetag" => ewiki_etag($data),
138 "getcontentlanguage" => EWIKI_DEFAULT_LANG,
139 "page:author" => $data["author"],
140 "page:version" => $data["version"],
141 "page:hits" => $data["hits"],
142 "page:log" => $data["meta"]["log"],
143 "page:user-agent" => $data["meta"]["user-agent"],
146 #-- add {meta}² entries
147 if ($meta = $data["meta"]["meta"]) foreach ($meta as $i=>$v) {
148 $m["meta:$i"] = implode(", ", $v);
155 #-- needed only for (virtual) root element/dir
156 function dirinfo(&$data) {
158 #-- create meta/properties array
159 $ct = "httpd/unix-directory";
161 "path" => "/" . trim($data["id"], "/"),
162 "resourcetype" => "collection", // it's a dir
163 "creationdate" => $data["created"],
164 "getcontentlength" => 0,
165 // "getlastmodified" => $data["lastmodified"],
166 "getcontenttype" => $ct,
167 // "displayname" => EWIKI_NAME.":",
175 #-- save page into database (no overwriting)
176 function PUT($path, $ct, $charset) {
178 #-- let's call the auth routine once more??
181 #-- get old page version
182 $id = $this->id($path);
183 ($data = ewiki_db::GET($id))
184 or ($data = ewiki_db::CREATE($id));
186 #-- read from whereever
187 $data["content"] = $this->get_body();
189 #-- check content-type
190 if (($ct != "text/wiki") && ($ct != "text/plain")) {
191 return("422 Only WikiPages Accepted");
195 ewiki_db::UPDATE($data);
196 $data["version"] += 1;
197 $ok = ewiki_db::WRITE($data);
199 #-- handle response here
201 return("200 Written Successfully");
203 return("500 Couldn't Save");
207 // #-- returns only the HTTP headers for a given page
209 // } // will anyhow get emulated via GET()
212 function PROPPATCH() {
216 #-- no real page deletion without authenticated admin/pw, and we
217 # simply clear the page, if it exists (content:="DeletedPage")
228 // #-- we could emulate this via 'plugins/edit/lock|warn'
231 // function UNLOCK() {
236 #-- just to be sure we call it again (already done in z.php)
239 include("plugins/../fragments/funcs/auth.php");
246 #-- decode page id from the $path arg
249 // if (strpos($id, EWIKI_SCRIPT_WEBDAV) === 0) {
250 // $id = substr($id, strlen(EWIKI_SCRIPT_WEBDAV));
252 #-- MiniDav base class always leaves the slash in (originally came from PATH_INFO)
254 $id = substr($id, 1);