Platform  3.1
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.FdlDav.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
5  * @package FDL
6 */
7 /**
8  * FREEDOM File system
9  *
10  * @author Anakeen 2006
11  * @version $Id: Class.FdlDav.php,v 1.18 2008/12/01 16:29:18 eric Exp $
12  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
13  * @package FDL
14  */
15 /**
16  */
17 
18 require_once "DAV/Class.ServerDav.php";
19 require_once "System.php";
20 /**
21  * Filesystem access using WebDAV
22  *
23  * @access public
24  */
26 {
27  /**
28  * Root directory for WebDAV access
29  *
30  * Defaults to webserver document root (set by ServeRequest)
31  *
32  * @access private
33  * @var string
34  */
35  var $base = "";
36 
37  public $db_freedom = "user=anakeen dbname=freedom";
38  /**
39  * Type : 'webdav' or 'freedav'
40  *
41  * Default type is 'webdav'
42  */
43  public $type = 'webdav';
44  /**
45  * Root directory id for WebDAV access
46  *
47  * Defaut root is 9 (freedom root folder)
48  *
49  * @var int
50  */
51  public $racine = 9;
52  /**
53  * Maximum number of documents listed in a folder
54  *
55  * Default is 'ALL' (no limit)
56  *
57  * @var int
58  */
59  private $folder_max_item = 'ALL';
60  /**
61  * PgSQL database for property/locking information storage
62  *
63  * @access private
64  * @var string
65  */
66  public $db_webdav = "dbname=webdav user=anakeen";
67 
68  private $db_res; // db ressource
69  function __construct($dbaccess = "")
70  {
71  // establish connection to property/locking db
72  if ($dbaccess != "") $this->db_webdav = $dbaccess;
73 
74  $this->db_res = pg_connect($this->db_webdav) or die("connection error");
75 
76  parent::__construct();
77  }
78  /**
79  * Serve a webdav request
80  *
81  * @access public
82  * @param string
83  */
84  function ServeRequest()
85  {
86  // special treatment for litmus compliance test
87  // reply on its identifier header
88  // not needed for the test itself but eases debugging
89  foreach (apache_request_headers() as $key => $value) {
90  if (stristr($key, "litmus")) {
91  error_log("Litmus test $value");
92  header("X-Litmus-reply: " . $value);
93  }
94  }
95  $this->base = "";
96  // TODO throw on connection problems
97  // let the base class do all the work
98  parent::ServeRequest();
99  }
100  /**
101  * No authentication is needed here
102  *
103  * @access private
104  * @param string HTTP Authentication type (Basic, Digest, ...)
105  * @param string Username
106  * @param string Password
107  * @return bool true on successful authentication
108  */
109  function check_auth($type, $user, $pass)
110  {
111  return true;
112  }
113  /**
114  * PROPFIND method handler
115  *
116  * @param array $options general parameter passing array
117  * @param array $files return array for file properties
118  * @return bool true on success
119  */
120  function PROPFIND(&$options, &$files)
121  {
122  // get absolute fs path to requested resource
123  $fspath = $options["path"];
124 
125  error_log(" >PROPFIND depth:" . $options["depth"]);
126  //$this->logArray($options);
127  // prepare property array
128  $files["files"] = array();
129  // store information for the requested path itself
130  // information for contained resources requested?
131  if (!empty($options["depth"])) { // TODO check for is_dir() first?
132  // make sure path ends with '/'
133  $options["path"] = $this->_slashify($options["path"]);
134  // try to open directory
135  $freefiles = $this->readfolder($fspath);
136  $files["files"] = $freefiles;
137  } else {
138 
139  $freefiles = $this->readfolder($fspath, true);
140  $files["files"] = $freefiles;
141  }
142 
143  if (count($files["files"]) == 0) return false;
144  // ok, all done
145  error_log("PROPFIND OK");
146  return true;
147  }
148 
149  function readfolder($fspath, $onlyfld = false)
150  {
151  include_once ('FDL/Class.SearchDoc.php');
152 
153  $files = array();
154  $fldid = $this->path2id($fspath, $vid);
155 
156  if (strtolower($fspath) == "/freedav") {
157  $info = array();
158  $info["props"] = array();
159  $info["props"][] = $this->mkprop("resourcetype", "collection");
160  $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
161  $info["props"][] = $this->mkprop("displayname", $fspath);
162  $info["path"] = $fspath;
163  $files[] = $info;
164  } else {
165  if ($vid) {
166  $files = $this->vidpropinfo($fspath, $fldid, (!$onlyfld));
167  } else {
168  $fld = new_doc($this->db_freedom, $fldid, true);
169  if ($fld->isAlive()) {
170  // error_log("READFOLDER FIRST:".dirname($fspath)."/".$fld->title."ONLY:".intval($onlyfld));
171  //$files=$this->docpropinfo($fld,$this->_slashify(dirname($fspath)),true);
172  if (($fld->doctype == 'D') || ($fld->doctype == 'S')) $dpath = $this->_slashify($fspath);
173  else $dpath = $fspath;
174  $files = $this->docpropinfo($fld, $dpath, true);
175  if (!$onlyfld) {
176  $s = new SearchDoc($this->db_freedom);
177  $s->dirid = $fld->initid;
178  $s->slice = $this->getFolderMaxItem();
179  $s->setObjectReturn();
180  $s->search();
181  if ($s->count() > 0) {
182  while ($doc = $s->nextDoc()) {
183  $files = array_merge($files, $this->docpropinfo($doc, $fspath, false));
184  }
185  }
186  }
187  }
188  }
189  }
190  return $files;
191  }
192 
193  private static function logArray($a, $level = 0)
194  {
195  if (is_array($a)) {
196  foreach ($a as $k => $v) {
197  error_log(str_pad('.', $level * 3) . "$k=>" . self::logArray($v, $level + 1));
198  }
199  } else {
200  error_log(str_pad('.', $level * 3) . $a);
201  }
202  }
203  function path2id($fspath, &$vid = null)
204  {
205  //error_log("FSPATH :".$fspath);
206  if ($fspath == '/') return $this->racine;
207 
208  $fspath = $this->_unslashify($fspath);
209  if (preg_match('/\/vid-([0-9]+)-([0-9]+)-[a-f0-9]+$/', $fspath, $reg)) {
210  // main directory
211  $fid = $reg[1];
212  $vid = $reg[2];
213  //error_log("FSPATH4 :.$fspath vid:[$vid]");
214  // $dvi=new DocVaultIndex($this->db_freedom);
215  //$fid=$dvi->getDocId($vid);
216  //error_log("FSPATH3 :.$fspath vid:[$vid]");
217 
218  } else if (preg_match('/\/vid-([0-9]+)-([0-9]+)/', $fspath, $reg)) {
219  include_once('FDL/Lib.Vault.php');
220  $fid = $reg[1];
221  $tmpvid = $reg[2];
222  $info=vault_properties($tmpvid);
223 
224  $fsbase = basename($fspath);
225  if ($info->name == $fsbase) {
226  $vid = $tmpvid;
227  } else {
228  $fid=0;
229  }
230  // error_log("FSPATH3 :.$fspath vid:[$vid]");
231 
232  } else {
233  if (!seems_utf8($fspath)) $fspath = utf8_encode($fspath);
234  $query = sprintf("SELECT value FROM dav.properties WHERE name='fid' and path = '%s'", pg_escape_string($fspath));
235 
236  $res = pg_query($this->db_res, $query);
237  while ($row = pg_fetch_assoc($res)) {
238  $fid = $row["value"];
239  }
240  // error_log("PATH2ID:".$query."[$fid]");
241  pg_free_result($res);
242  }
243  // error_log("FSPATH :".$fspath. "=>".$fid);
244  return $fid;
245  }
246 
248  {
249  $fileAttributes = $doc->GetFileAttributes();
250  $tinfo = array();
251  foreach ($fileAttributes as $fileAttribute) {
252  if ($fileAttribute->getOption('hideindav') == 'yes') {
253  continue;
254  }
255  $result = $doc->vault_properties($fileAttribute);
256  if (count($result) > 0 && is_array($result[0])) {
257  foreach ($result as $tmp) {
258  $state = intval($tmp["teng_state"]);
259  if ($state == 0 || $state == 1) { // only valid files
260  $tinfo[] = $tmp;
261  }
262  }
263  }
264  }
265  return $tinfo;
266  }
267 
268  function docpropinfo(&$doc, $path, $firstlevel)
269  {
270  // error_log("docpropinfo $doc->initid $doc->id $path #$firstlevel");
271  // map URI path to filesystem path
272  $fspath = $this->base . $path;
273  // create result array
274  $tinfo = array();
275  $info = array();
276  // TODO remove slash append code when base clase is able to do it itself
277  //$info["path"] = is_dir($fspath) ? $this->_slashify($path) : $path;
278  if ($doc->id == $this->racine) $doc->title = '';
279  // no special beautified displayname here ...
280  // creation and modification time
281  // type and size (caller already made sure that path exists)
282  if (($doc->doctype == 'D') || ($doc->doctype == 'S')) {
283  // directory (WebDAV collection)
284  $info = array();
285  $info["props"] = array();
286  $info["props"][] = $this->mkprop("resourcetype", "collection");
287  $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
288  $info["props"][] = $this->mkprop("displayname", strtr($doc->title, "/", "-"));
289  $path = $this->_slashify($path);
290  if ($firstlevel) $info["path"] = $path;
291  else $info["path"] = $path . strtr($doc->title, "/", "-");
292  //$info["path"] = $path;
293  $info["props"][] = $this->mkprop("creationdate", $doc->revdate);
294  $info["props"][] = $this->mkprop("getlastmodified", $doc->revdate);
295  //error_log("FOLDER:".$path.":".$doc->title);
296  // get additional properties from database
297  $query = sprintf("SELECT ns, name, value FROM dav.properties WHERE path = '%s'", pg_escape_string($path));
298  $res = pg_query($this->db_res, $query);
299  while ($row = pg_fetch_assoc($res)) {
300  $info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]);
301  }
302  pg_free_result($res);
303  $tinfo[] = $info;
304  if (($firstlevel) || ($doc->title != "")) {
305  //$query = "REPLACE INTO dav.properties SET path = '".pg_escape_string($this->_unslashify($info["path"]))."', name = 'fid', ns= '$prop[ns]', value = '".$doc->initid."'";
306  $query = sprintf("delete from dav.properties where path= '%s' and name= 'fid'", pg_escape_string($this->_unslashify($info["path"])));
307 
308  pg_query($this->db_res, $query);
309  $query = sprintf("INSERT INTO dav.properties (path, name, ns, value) values ('%s', 'fid', '%s', '%s')", pg_escape_string($this->_unslashify($info["path"])) , pg_escape_string($prop['ns']) , pg_escape_string($doc->initid));
310 
311  pg_query($this->db_res, $query);
312  }
313  } else {
314  // simple document : search attached files
315  // $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath));
316  $afiles = $this->GetFilesProperties($doc);
317  //error_log("READFILES examine :".count($afiles).'-'.$doc->title.'-'.$doc->id);
318  $bpath = $this->mybasename($path);
319  $dpath = $this->_slashify(dirname($path));
320  //error_log("FILEDEBUG:".$path."-".$bpath."- $path #$firstlevel");
321  $path = $this->_slashify($path);
322  foreach ($afiles as $afile) {
323  $info = array();
324  $info["props"][] = $this->mkprop("resourcetype", "");
325  $aname = strtr($afile["name"], "/", "-");
326  //error_log("FILE TEST [$aname] [$bpath] #$firstlevel");
327  if ((!$firstlevel) || ($aname == $bpath)) {
328  if ($firstlevel) $info["path"] = $dpath . $aname;
329  else $info["path"] = $path . $aname;
330  $filename = $afile["path"];
331 
332  if (file_exists($filename)) {
333  $info["props"][] = $this->mkprop("displayname", $aname);
334  $info["props"][] = $this->mkprop("creationdate", filectime($filename));
335  $info["props"][] = $this->mkprop("getlastmodified", filemtime($filename));
336  $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($filename));
337  $info["props"][] = $this->mkprop("getcontentlength", intval($afile["size"]));
338  // get additional properties from database
339  $query = sprintf("SELECT ns, name, value FROM dav.properties WHERE path = '%s'", pg_escape_string($this->_unslashify($info["path"])));
340  $res = pg_query($this->db_res, $query);
341  while ($row = pg_fetch_assoc($res)) {
342  $info["props"][] = $this->mkprop($row["ns"], $row["name"], $row["value"]);
343  }
344  pg_free_result($res);
345  // error_log("PROP:".print_r($info,true));
346  // error_log("PROP:".$query);
347  $tinfo[] = $info;
348  //$query = "REPLACE INTO properties SET path = '".pg_escape_string($this->_unslashify($info["path"]))."', name = 'fid', ns= '$prop[ns]', value = '".$doc->id."'";
349  $query = sprintf("delete from dav.properties where path= '%s' and name= 'fid'", pg_escape_string($this->_unslashify($info["path"])));
350  pg_query($this->db_res, $query);
351  $query = sprintf("INSERT INTO dav.properties (path, name, ns, value) values ('%s', 'fid', '%s', '%s')", pg_escape_string($this->_unslashify($info["path"])) , pg_escape_string($prop['ns']) , pg_escape_string($doc->initid));
352  pg_query($this->db_res, $query);
353  // error_log($query);
354  //error_log("FILE:".$afile["name"]."-".$afile["size"]."-".$path);
355 
356  } else {
357  error_log("FILE ERROR:" . $doc->title . "-" . $doc->id . "-" . $filename);
358  }
359  }
360  //error_log("PROP:".$query);
361 
362  }
363  }
364 
365  return $tinfo;
366  }
367  /**
368  * virtual path
369  */
370  function vidpropinfo($path, $docid, $withfile = false)
371  {
372  // map URI path to filesystem path
373  // create result array
374  $tinfo = array();
375  $info = array();
376  // TODO remove slash append code when base clase is able to do it itself
377  //$info["path"] = is_dir($fspath) ? $this->_slashify($path) : $path;
378  // no special beautified displayname here ...
379  $onlyfile = false;
380  if (preg_match("/\/vid-([^\/]*)\/(.*)/", $path, $reg)) {
381  $onlyfile = $reg[2];
382  }
383  // creation and modification time
384  // directory (WebDAV collection)
385  if (!$onlyfile) {
386  $info = array();
387  $info["props"] = array();
388  $info["props"][] = $this->mkprop("resourcetype", "collection");
389  $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
390  $info["props"][] = $this->mkprop("displayname", $path);
391  // $info["props"][] = $this->mkprop("urn:schemas-microsoft-com:", "Win32FileAttributes", "00000001");
392  $path = $this->_slashify($path);
393  if ($firstlevel) $info["path"] = $path;
394  else $info["path"] = $path;
395  //$info["path"] = $path;
396  $info["props"][] = $this->mkprop("creationdate", time());
397  $info["props"][] = $this->mkprop("getlastmodified", time());
398  //error_log("VIRTUAL FOLDER:".$path.":");
399 
400  }
401  $tinfo[] = $info;
402  if ($withfile || $onlyfile) {
403  // simple document : search attached files
404  $doc = new_doc($this->db_freedom, $docid, true);
405  // $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath));
406  $afiles = $this->GetFilesProperties($doc);
407  //error_log("VIDPROP examine :".count($afiles).'-'.$doc->title.'-'.$doc->id);
408  $bpath = $this->mybasename($path);
409  $dpath = $this->_slashify(dirname($path));
410  //error_log("FILEDEBUG:".$path."-".$bpath."-".$path);
411  $path = $this->_slashify($path);
412  foreach ($afiles as $afile) {
413  $aname = $afile["name"];
414  //error_log("SEARCH FILE:[$aname] [$onlyfile]");
415  if ((!$onlyfile) || ($aname == $onlyfile)) {
416  $info = array();
417  //error_log("FOUND FILE:".$aname);
418  $info["props"][] = $this->mkprop("resourcetype", "");
419 
420  $info["props"][] = $this->mkprop("displayname", $aname);
421  if ($firstlevel) $info["path"] = $dpath . $aname;
422  else $info["path"] = $path . $aname;
423  $filename = $afile["path"];
424  $info["props"][] = $this->mkprop("creationdate", filectime($filename));
425  $info["props"][] = $this->mkprop("getlastmodified", filemtime($filename));
426  $info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($filename));
427  $info["props"][] = $this->mkprop("getcontentlength", intval($afile["size"]));
428  $err = $doc->canEdit();
429  if ($err != "") {
430  // add read only attributes for windows
431  $info["props"][] = $this->mkprop("urn:schemas-microsoft-com:", "Win32FileAttributes", "00000001");
432  }
433  $tinfo[] = $info;
434  }
435  //error_log("PROP:".$query);
436 
437  }
438  }
439 
440  return $tinfo;
441  }
442  /**
443  * detect if a given program is found in the search PATH
444  *
445  * helper function used by _mimetype() to detect if the
446  * external 'file' utility is available
447  *
448  * @param string program name
449  * @param string optional search path, defaults to $PATH
450  * @return bool true if executable program found in path
451  */
452  function _can_execute($name, $path = false)
453  {
454  // path defaults to PATH from environment if not set
455  if ($path === false) {
456  $path = getenv("PATH");
457  }
458  // check method depends on operating system
459  if (!strncmp(PHP_OS, "WIN", 3)) {
460  // on Windows an appropriate COM or EXE file needs to exist
461  $exts = array(
462  ".exe",
463  ".com"
464  );
465  $check_fn = "file_exists";
466  } else {
467  // anywhere else we look for an executable file of that name
468  $exts = array(
469  ""
470  );
471  $check_fn = "is_executable";
472  }
473  // now check the directories in the path for the program
474  foreach (explode(PATH_SEPARATOR, $path) as $dir) {
475  // skip invalid path entries
476  if (!file_exists($dir)) continue;
477  if (!is_dir($dir)) continue;
478  // and now look for the file
479  foreach ($exts as $ext) {
480  if ($check_fn("$dir/$name" . $ext)) return true;
481  }
482  }
483 
484  return false;
485  }
486  /**
487  * try to detect the mime type of a file
488  *
489  * @param string file path
490  * @return string guessed mime type
491  */
492  function _mimetype($fspath)
493  {
494  return strtok(trim(shell_exec(sprintf("file -ib %s", escapeshellarg($fspath)))) , ';');
495  if (@is_dir($fspath)) {
496  // directories are easy
497  return "httpd/unix-directory";
498  } else if (function_exists("mime_content_type")) {
499  // use mime magic extension if available
500  $mime_type = mime_content_type($fspath);
501  } else if ($this->_can_execute("file")) {
502  // it looks like we have a 'file' command,
503  // lets see it it does have mime support
504  $fp = popen("file -i '$fspath' 2>/dev/null", "r");
505  $reply = fgets($fp);
506  pclose($fp);
507  // popen will not return an error if the binary was not found
508  // and find may not have mime support using "-i"
509  // so we test the format of the returned string
510  // the reply begins with the requested filename
511  if (!strncmp($reply, "$fspath: ", strlen($fspath) + 2)) {
512  $reply = substr($reply, strlen($fspath) + 2);
513  // followed by the mime type (maybe including options)
514  if (preg_match('/^[[:alnum:]_-]+/[[:alnum:]_-]+;?.*/', $reply, $matches)) {
515  $mime_type = $matches[0];
516  }
517  }
518  }
519 
520  if (empty($mime_type)) {
521  // Fallback solution: try to guess the type by the file extension
522  // TODO: add more ...
523  // TODO: it has been suggested to delegate mimetype detection
524  // to apache but this has at least three issues:
525  // - works only with apache
526  // - needs file to be within the document tree
527  // - requires apache mod_magic
528  // TODO: can we use the registry for this on Windows?
529  // OTOH if the server is Windos the clients are likely to
530  // be Windows, too, and tend do ignore the Content-Type
531  // anyway (overriding it with information taken from
532  // the registry)
533  // TODO: have a seperate PEAR class for mimetype detection?
534  switch (strtolower(strrchr($this->mybasename($fspath) , "."))) {
535  case ".html":
536  $mime_type = "text/html";
537  break;
538 
539  case ".gif":
540  $mime_type = "image/gif";
541  break;
542 
543  case ".jpg":
544  $mime_type = "image/jpeg";
545  break;
546 
547  default:
548  $mime_type = "application/octet-stream";
549  break;
550  }
551  }
552 
553  return $mime_type;
554  }
555  /**
556  * GET method handler
557  *
558  * @param array parameter passing array
559  * @return bool true on success
560  */
561  function GET(&$options)
562  {
563  error_log("---------->GET :" . $options["path"]);
564  include_once ("FDL/Class.Doc.php");
565  // get absolute fs path to requested resource
566  $fspath = $this->base . $options["path"];
567 
568  $fldid = $this->path2id($options["path"], $vid);
569  $doc = new_doc($this->db_freedom, $fldid, true);
570  if (!$doc->isAlive()) {
571  $this->cleanDeleted($fldid);
572  return false;
573  }
574  $afiles = $this->GetFilesProperties($doc);
575 
576  $bpath = $options["path"];
577  if (!seems_utf8($bpath)) $bpath = utf8_encode($bpath);
578 
579  $bpath = $this->mybasename($bpath); // basename
580  foreach ($afiles as $afile) {
581  $path = $afile["name"];
582  //error_log("GET SEARCH:".$bpath.'->'.$path);
583  if (($vid == $afile["vid"]) || ($path == $bpath)) {
584  error_log("GET FOUND:" . $path . '-' . $afile["path"]);
585  $fspath = $afile["path"];
586  break;
587  }
588  }
589  // sanity check
590  if (!file_exists($fspath)) return false;
591  // is this a collection?
592  if (is_dir($fspath)) {
593  return $this->GetDir($fspath, $options);
594  }
595  // detect resource type
596  $options['mimetype'] = $this->_mimetype($fspath);
597  // detect modification time
598  // see rfc2518, section 13.7
599  // some clients seem to treat this as a reverse rule
600  // requiering a Last-Modified header if the getlastmodified header was set
601  $options['mtime'] = filemtime($fspath);
602  // detect resource size
603  $options['size'] = filesize($fspath);
604  // no need to check result here, it is handled by the base class
605  $options['stream'] = fopen($fspath, "r");
606 
607  header("Cache-control: no-cache");
608  header("Pragma: no-cache"); // HTTP 1.0
609  error_log("GET NO CACHE :" . $options["path"]);
610  return true;
611  }
612  /**
613  * GET method handler for directories
614  *
615  * This is a very simple mod_index lookalike.
616  * See RFC 2518, Section 8.4 on GET/HEAD for collections
617  *
618  * @param string directory path
619  * @return void function has to handle HTTP response itself
620  */
621  function GetDir($fspath, &$options)
622  {
623 
624  echo "<html><head><title>Index of " . htmlspecialchars($options['path']) . "</title></head>\n";
625 
626  echo "<h1>Index of " . htmlspecialchars($options['path']) . "</h1>\n";
627 
628  echo "<pre>WebDAV Server: HTML view is not implemented yet";
629 
630  echo "<hr>";
631 
632  echo "</pre>";
633 
634  echo "</html>\n";
635 
636  exit;
637  }
638  /**
639  * PUT method handler
640  *
641  * @param array parameter passing array
642  * @return bool true on success
643  */
644  function PUT(&$options)
645  {
646  error_log("---------->PUT :" . $options["path"]);
647  include_once ("FDL/Class.Doc.php");
648 
649  $bpath = $this->mybasename($options["path"]);
650  if (!seems_utf8($bpath)) $bpath = utf8_encode($bpath);
651  $fldid = $this->path2id($options["path"], $vid);
652  if ($fldid) {
653  $stat = "204 No Content";
654  $options["new"] = false;
655  $doc = new_doc($this->db_freedom, $fldid, true);
656  $err = $doc->canEdit();
657  if ($err == "") {
658  if ($doc->doctype == 'C') {
659  /*
660  * @var DocFam $doc
661  */
662  $doc->saveVaultFile($vid, $options["stream"]);
663  } else {
664  $afiles = $doc->GetFileAttributes();
665  //error_log("PUT SEARCH FILES:".count($afiles));
666 
667  /*
668  * @var NormalAttribute $afile
669  */
670  foreach ($afiles as $afile) {
671  if ($afile->getOption('hideindav') == 'yes') {
672  continue;
673  }
674  $fnames = array();
675  if ($afile->inArray()) {
676  $tval = $doc->getTValue($afile->id);
677  foreach ($tval as $k => $v) {
678  $fnames[$k] = $doc->vault_filename($afile->id, false, $k);
679  }
680  } else $fnames[-1] = $doc->vault_filename($afile->id);
681  foreach ($fnames as $k => $fname) {
682  // error_log("PUT SEARCH:.$bpath $fname");
683  if ($fname == $bpath) {
684  error_log("PUT FOUND:" . $path . '-' . $fname);
685 
686  $bpath = $bpath;
687  $doc->saveFile($afile->id, $options["stream"], $bpath, $k);
688  $err = $doc->postModify();
689  $err = $doc->Modify();
690 
691  break;
692  }
693  }
694  }
695  }
696  }
697  } else {
698  error_log("PUT " . $this->type);
699  if ($this->type == 'freedav') {
700  error_log(" CANCEL PUT :" . $options["path"]);
701  return false; // no creation in freedav
702 
703  }
704  $options["new"] = true;
705  $stat = "201 Created";
706  if ($options["new"]) {
707  $dir = dirname($options["path"]);
708  $fldid = $this->path2id($dir);
709  $fld = new_doc($this->db_freedom, $fldid);
710  $err = $fld->canModify();
711  if ($err == "") {
712  //error_log("PUT NEW FILE IN:".$dir);
713  $ndoc = createDoc($this->db_freedom, "SIMPLEFILE");
714  if ((!$ndoc) || (!$ndoc->fromid)) $ndoc = createDoc($this->db_freedom, "FILE");
715  if ($ndoc && $ndoc->fromid) {
716  $fa = $ndoc->GetFirstFileAttributes();
717  $bpath = $bpath;
718  $ndoc->saveFile($fa->id, $options["stream"], $bpath);
719  // $ndoc->setTitle($bpath);
720  $err = $ndoc->Add();
721  $err = $ndoc->postModify();
722  $err = $ndoc->Modify();
723  error_log("PUT NEW FILE:" . $fa->id . "-" . $ndoc->id);
724  if ($err == "") {
725  $err = $fld->addFile($ndoc->initid);
726  error_log("PUT ADD IN FOLDER:" . $err . $fld->id . "UID:" . ($fld->userid));
727  $this->readfolder($dir);
728  }
729  } else {
730  $err = "not allowed";
731  }
732  }
733  }
734  }
735  if (!$err) {
736  error_log(" CREATE PUT OK :" . $options["path"]);
737  } else {
738  error_log(" CREATE PUT KO : $err:" . $options["path"]);
739  }
740  if ($err != "") $stat = false;
741 
742  return $stat;
743  }
744  /**
745  * MKCOL method handler
746  *
747  * @param array general parameter passing array
748  * @return bool true on success
749  */
750  function MKCOL($options)
751  {
752 
753  error_log("---------- >MKCOL :" . $options["path"]);
754  $err='';
755  include_once ("FDL/Class.Doc.php");
756 
757  if (!empty($_SERVER["CONTENT_LENGTH"])) { // no body parsing yet
758  return "415 Unsupported media type";
759  }
760  $path = $this->_unslashify($options["path"]);
761  $fldid = $this->path2id(dirname($options["path"]));
762  if ($fldid) {
763  $fld = new_doc($this->db_freedom, $fldid);
764  $nfld = createDoc($this->db_freedom, "SIMPLEFOLDER");
765  if ((!$nfld) || (!$nfld->fromid)) $nfld = createDoc($this->db_freedom, "DIR");
766  if ((!$nfld) || (!$nfld->fromid)) return "403 Forbidden : $err";
767  $nreptitle = $this->mybasename($path);
768  $nfld->setTitle($nreptitle);
769  $err = $nfld->Add();
770  if ($err == "") {
771  $err = $fld->AddFile($nfld->initid);
772  error_log("NEW FLD:" . $nfld->initid);
773  $this->docpropinfo($nfld, $path, true);
774  }
775  }
776  /*
777  if (!file_exists($parent)) {
778  return "409 Conflict";
779  }
780 
781  if (!is_dir($parent)) {
782  $name = $this->mybasename($path); return "403 Forbidden";
783  }
784 
785  if ( file_exists($parent."/".$name) ) {
786  return "405 Method not allowed";
787  }
788  */
789 
790  if ($err != "") {
791  return "403 Forbidden : $err";
792  }
793 
794  return ("201 Created");
795  }
796  /**
797  * DELETE method handler
798  *
799  * @param array general parameter passing array
800  * @return bool true on success
801  */
802  function DELETE($options)
803  {
804  error_log("---------- >DELETE :" . $options["path"]);
805 
806  if ($this->type == 'freedav') {
807  $err = sprintf("unsupported DELETE method with freedav access.");
808  error_log(sprintf("---------- > %s", $err));
809  return "403 Forbidden: $err";
810  }
811 
812  include_once ("FDL/Class.Doc.php");
813  $fldid = $this->path2id($options["path"]);
814  $doc = new_doc($this->db_freedom, $fldid, true);
815 
816  if (!$doc->isAlive()) {
817  return "404 Not found";
818  }
819  if ($doc->doctype == 'D') {
820  // just rm the folder : is normally empty
821  $err = $doc->delete();
822  if ($err != "") {
823  return "403 Forbidden:$err";
824  }
825  if ($err == "") {
826  $query = sprintf("DELETE FROM dav.properties WHERE path LIKE '%s%%'", pg_escape_string($this->_slashify($options["path"])));
827  pg_query($this->db_res, $query);
828  }
829  } else {
830  if ($doc->isLocked()) {
831  $err = $doc->unlock();
832  }
833 
834  if ($err != "") {
835  return "403 Forbidden:$err";
836  }
837  $err = $doc->delete();
838  if ($err != "") {
839  return "403 Forbidden:$err";
840  }
841  $query = sprintf("DELETE FROM dav.properties WHERE name='fid' and value='%s'", pg_escape_string($doc->initid));
842  error_log($query);
843  pg_query($this->db_res, $query);
844  }
845 
846  return "204 No Content";
847  }
848  /**
849  * MOVE method handler
850  *
851  * @param array general parameter passing array
852  * @return bool true on success
853  */
854  function MOVE($options)
855  {
856  error_log("---------- >MOVE :" . $options["path"] . "->" . $options["dest"]);
857  // no copying to different WebDAV Servers yet
858  if (isset($options["dest_url"])) {
859  return "502 bad gateway";
860  }
861 
862  include_once ("FDL/Class.Doc.php");
863  $psource = $this->_unslashify($options["path"]);
864  $pdirsource = $this->_unslashify(dirname($options["path"]));
865  $bsource = $this->mybasename($psource);
866 
867  $srcid = $this->path2id($psource);
868  $src = new_doc($this->db_freedom, $srcid);
869  //error_log ("SRC : $psource ".$srcid );
870  $err = $src->canEdit();
871  if ($err == "") {
872 
873  $pdest = $this->_unslashify($options["dest"]);
874  $bdest = $this->mybasename($pdest);
875  $destid = $this->path2id($pdest);
876 
877  $pdirdest = $this->_unslashify(dirname($options["dest"]));
878  $dirdestid = $this->path2id($pdirdest);
879  $ppdest = new_doc($this->db_freedom, $dirdestid);
880 
881  if ($destid) {
882  $dest = new_doc($this->db_freedom, $destid);
883  if ($dest->doctype == 'D') {
884  //error_log ("MOVE TO FOLDER : $destid:".$dest->title);
885  return "502 bad gateway";
886  } else {
887 
888  error_log("DELETE FILE : $destid:" . $dest->title);
889  // delete file
890  $err = $dest->delete();
891  if ($err == "") {
892  $query = sprintf("DELETE FROM dav.properties WHERE name='fid' and value='%s'", pg_escape_string($dest->initid));
893  error_log($query);
894  pg_query($this->db_res, $query);
895  // move
896  $err = $ppdest->addFile($srcid);
897  if ($err == "") {
898  // delete ref from source
899  $psrcid = $this->path2id($pdirsource);
900  $psrc = new_doc($this->db_freedom, $psrcid);
901  if ($psrc->isAlive()) {
902  $err = $psrc->delFile($srcid);
903  if ($err == "") {
904 
905  $src->addComment(sprintf(_("Move file from %s to %s") , ($psrc->title) , ($ppdest->title)));
906  $query = "DELETE FROM dav.properties WHERE path = '$psource'";
907  }
908  }
909  }
910  }
911 
912  if ($bdest != $bsource) {
913  error_log(" RENAMETO2 : $bdest");
914  $src->setTitle($bdest);
915  $err = $src->modify();
916  $this->docpropinfo($src, $pdest, true);
917  if ($err == "") {
918 
919  $query = sprintf("DELETE FROM dav.properties WHERE path = '%s'", pg_escape_string($psource));
920  error_log($query);
921  pg_query($this->db_res, $query);
922  }
923  error_log(" RENAMETO : $bdest : $err");
924  }
925  }
926  } else {
927  if ($pdirsource != $pdirdest) {
928  // move
929  $err = $ppdest->addFile($srcid);
930  if ($err == "") {
931  $this->docpropinfo($src, $pdest, true);
932  // delete ref from source
933  $psrcid = $this->path2id($pdirsource);
934  $psrc = new_doc($this->db_freedom, $psrcid);
935  if ($psrc->isAlive()) {
936  $err = $psrc->delFile($srcid);
937  if ($err == "") {
938  $src->addComment(sprintf(_("Move file from %s to %s") , ($psrc->title) , ($ppdest->title)));
939  $query = sprintf("DELETE FROM dav.properties WHERE path = '%s'", pg_escape_string($psource));
940  pg_query($this->db_res, $query);
941  }
942  }
943  }
944  error_log("MOVE TO PARENT2 FOLDER : $dirdestid:" . $err);
945  }
946  if ($err == "") {
947  if ($bdest != $bsource) {
948  if ($src->doctype == 'D') {
949  $src->setTitle($bdest);
950  } else {
951 
952  $afiles = $this->GetFilesProperties($src);
953  foreach ($afiles as $afile) {
954  $path = $afile["name"];
955  error_log("RENAME SEARCH:" . $bsource . '->' . $path);
956  if ($path == $bsource) {
957  error_log("RENAME FOUND:" . $path . '-' . $afile["path"]);
958  $fspath = $afile["path"];
959 
960  $vf = newFreeVaultFile($this->db_freedom);
961  $vf->Rename($afile["vid"], $bdest);
962  $src->addComment(sprintf(_("Rename file as %s") , $bdest));
963  $src->postModify();
964  $err = $src->modify();
965  }
966  }
967  }
968  $err = $src->modify();
969  $this->docpropinfo($src, $pdest, true);
970  if ($err == "") {
971 
972  $query = sprintf("DELETE FROM dav.properties WHERE path = '%s'", pg_escape_string($psource));
973  error_log($query);
974  pg_query($this->db_res, $query);
975  }
976  error_log(" RENAMETO2 : $bdest : $err");
977  }
978  }
979  }
980  if ($src->doctype == 'D') {
981  $query = sprintf("UPDATE dav.properties SET path = REPLACE(path, '%s', '%s') WHERE path LIKE '%s%%'", pg_escape_string($psource) , pg_escape_string($pdest) , pg_escape_string($psource));
982  pg_query($this->db_res, $query);
983  error_log($query);
984  }
985 
986  if ($err == "") return "201 Created";
987  }
988  error_log("DAV MOVE:$err");
989  return "403 Forbidden";
990  }
991  /**
992  * COPY method handler
993  *
994  * @param array general parameter passing array
995  * @return bool true on success
996  */
997  function COPY($options)
998  {
999  error_log("---------- >COPY :" . $options["path"] . "->" . $options["dest"]);
1000  // no copying to different WebDAV Servers yet
1001  if (isset($options["dest_url"])) {
1002  return "502 bad gateway";
1003  }
1004 
1005  include_once ("FDL/Class.Doc.php");
1006  $psource = $this->_unslashify($options["path"]);
1007  $pdirsource = $this->_unslashify(dirname($options["path"]));
1008  $bsource = $this->mybasename($psource);
1009 
1010  $srcid = $this->path2id($psource);
1011  $src = new_doc($this->db_freedom, $srcid);
1012  error_log("SRC : $psource " . $srcid);
1013 
1014  $pdest = $this->_unslashify($options["dest"]);
1015  $bdest = $this->mybasename($pdest);
1016  $destid = $this->path2id($pdest);
1017 
1018  $pdirdest = $this->_unslashify(dirname($options["dest"]));
1019  $dirdestid = $this->path2id($pdirdest);
1020  $ppdest = new_doc($this->db_freedom, $dirdestid);
1021 
1022  if ($destid) {
1023  $dest = new_doc($this->db_freedom, $destid);
1024  if ($dest->doctype == 'D') {
1025  error_log("COPY FILE TO REPLACE FOLDER NOT POSSIBLE NORMALLY: $destid:" . $dest->title);
1026  return "502 bad gateway";
1027  } else {
1028  error_log("DELETE FILE : $destid:" . $dest->title);
1029  // delete file
1030  $err = $dest->delete();
1031 
1032  if ($err == "") {
1033 
1034  $query = sprintf("DELETE FROM dav.properties WHERE name='fid' and value='%s'", pg_escape_string($dest->initid));
1035  error_log($query);
1036  pg_query($this->db_res, $query);
1037  }
1038  }
1039  }
1040  if ($err == "") {
1041  // copy
1042  if ($src->doctype == "D") {
1043  // copy of directory
1044  return "501 not implemented";
1045  } else {
1046 
1047  $copy = $src->copy();
1048 
1049  error_log("COPY :" . $copy->id);
1050  $afiles = $this->GetFilesProperties($copy);
1051  error_log("# FILE :" . count($afiles));
1052  $ff = $copy->GetFirstFileAttributes();
1053 
1054  $f = $copy->getValue($ff->id);
1055  error_log("RENAME SEARCH:" . $f);
1056  if (preg_match(PREGEXPFILE, $f, $reg)) {
1057  $vf = newFreeVaultFile($this->db_freedom);
1058  $vid = $reg[2];
1059 
1060  $vf->Rename($vid, $bdest);
1061  $copy->addComment(sprintf(_("Rename file as %s") , $bdest));
1062  $copy->postModify();
1063  $err = $copy->modify();
1064  }
1065 
1066  $err = $ppdest->addFile($copy->id);
1067  if ($err == "") {
1068  $this->docpropinfo($copy, $pdest, true);
1069  }
1070 
1071  error_log("MOVE TO PARENT FOLDER : $dirdestid:" . $err);
1072  if ($bdest != $bsource) {
1073  $copy->setTitle($bdest);
1074  $err = $copy->modify();
1075  $this->docpropinfo($copy, $pdest, true);
1076 
1077  error_log(" RENAMETO : $bdest : $err");
1078  }
1079  }
1080  }
1081 
1082  if ($err == "") return "201 Created";
1083 
1084  error_log("DAV MOVE:$err");
1085  return "403 Forbidden";
1086  }
1087  /**
1088  * PROPPATCH method handler
1089  *
1090  * @param array general parameter passing array
1091  * @return bool true on success
1092  */
1093  function PROPPATCH(&$options)
1094  {
1095  global $prefs, $tab;
1096  error_log("---------- >PROPPATCH :" . $options["path"]);
1097 
1098  $msg = "";
1099 
1100  $path = $options["path"];
1101 
1102  $dir = dirname($path) . "/";
1103  $base = $this->mybasename($path);
1104 
1105  foreach ($options["props"] as $key => $prop) {
1106  if ($prop["ns"] == "DAV:") {
1107  $options["props"][$key]['status'] = "403 Forbidden";
1108  } else {
1109  if (isset($prop["val"])) {
1110  //$query = "REPLACE INTO properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'";
1111  $query = sprintf("delete from dav.properties where path='%s' and name= '%s' and ns='%s'", pg_escape_string($prop['path']) , pg_escape_string($prop['name']) , pg_escape_string($prop['ns']));
1112  pg_query($this->db_res, $query);
1113  $query = sprintf("INSERT INTO dav.properties (path, name, ns, value) values ('%s', '%s', '%s', '%s')", pg_escape_string($prop['path']) , pg_escape_string($prop['name']) , pg_escape_string($prop['ns']) , pg_escape_string($prop['val']));
1114  // pg_query($this->db_res,$query);
1115  // $query = "REPLACE INTO properties SET path = '$options[path]', name = '$prop[name]', ns= '$prop[ns]', value = '$prop[val]'";
1116 
1117  } else {
1118  $query = sprintf("DELETE FROM dav.properties WHERE path = '%s' AND name = '%s' AND ns = '%s'", pg_escape_string($options['path']) , pg_escape_string($prop['name']) , pg_escape_string($prop['ns']));
1119  }
1120  pg_query($this->db_res, $query);
1121  }
1122  }
1123 
1124  return "";
1125  }
1126  /**
1127  * LOCK method handler
1128  *
1129  * @param array general parameter passing array
1130  * @return bool true on success
1131  */
1132  function LOCK(&$options)
1133  {
1134  error_log("---------- >LOCK :" . $options["path"]);
1135  include_once ("FDL/Class.Doc.php");
1136  if (isset($options["update"])) { // Lock Update
1137  $query = sprintf("UPDATE dav.locks SET expires = %s where token='%s'", pg_escape_string((time() + 300)) , pg_escape_string($options["update"]));
1138  $res = pg_query($this->db_res, $query);
1139 
1140  if (pg_affected_rows($res)) {
1141  $options["timeout"] = 300; // 5min hardcoded
1142  error_log("LOCK Update succeed");
1143  return true;
1144  } else {
1145  error_log(print_r($options, true));
1146  error_log($query);
1147  error_log(pg_last_error($this->db_res));
1148  error_log("LOCK Update failed");
1149  return false;
1150  }
1151  }
1152 
1153  $fldid = $this->path2id($options["path"], $vid);
1154  $doc = new_doc($this->db_freedom, $fldid, true);
1155  if ($doc->isAffected()) {
1156  error_log("LOCK " . $doc->title . ":" . $options['locktoken']);
1157 
1158  $err = $doc->lock(true);
1159  if ($err == "") {
1160  $options["timeout"] = time() + 300; // 5min. hardcoded
1161  $query = sprintf("INSERT INTO dav.locks (token,path,owner,expires,exclusivelock) values ('%s', '%s', '%s', '%s', %s)", pg_escape_string($options['locktoken']) , pg_escape_string($options['path']) , pg_escape_string($options['owner']) , pg_escape_string($options['timeout']) , ($options['scope'] === "exclusive" ? "1" : "0"));
1162 
1163  $res = pg_query($this->db_res, $query);
1164  if (pg_affected_rows($res)) {
1165  return "200 OK";
1166  }
1167  } else {
1168  error_log("Cannot lock " . $doc->title . ":$err");
1169  }
1170  } else {
1171  return true;
1172  }
1173  return "409 Conflict";
1174  }
1175  /**
1176  * UNLOCK method handler
1177  *
1178  * @param array general parameter passing array
1179  * @return bool true on success
1180  */
1181  function UNLOCK(&$options)
1182  {
1183 
1184  error_log("---------- >UNLOCK :" . $options["path"]);
1185  include_once ("FDL/Class.Doc.php");
1186  $fldid = $this->path2id($options["path"], $vid);
1187  $doc = new_doc($this->db_freedom, $fldid, true);
1188 
1189  if ($doc->isAffected()) {
1190  $err = $doc->unlock(true);
1191  if ($err == "") {
1192  $query = sprintf("DELETE FROM dav.locks WHERE path = '%s' AND token = '%s'", pg_escape_string($options['path']) , pg_escape_string($options['token']));
1193  $res = pg_query($this->db_res, $query);
1194  if (pg_affected_rows($res)) {
1195  error_log(" unlock success :" . $doc->title . ":" . $options['token']);
1196  return "204 No Content";
1197  }
1198  }
1199  } else {
1200  return "204 No Content";
1201  }
1202  error_log("Cannot unlock " . $doc->title . ":[$err][" . $options['token']) . "]";
1203  return "409 Conflict";
1204  }
1205  /**
1206  * checkLock() helper
1207  *
1208  * @param string resource path to check for locks
1209  * @return bool true on success
1210  */
1211  function checkLock($path)
1212  {
1213  $result = false;
1214  if (!seems_utf8($path)) $path = utf8_encode($path);
1215  $query = sprintf("SELECT owner, token, expires, exclusivelock FROM dav.locks WHERE path = '%s'", pg_escape_string($path));
1216 
1217  $res = pg_query($this->db_res, $query);
1218 
1219  if ($res) {
1220  $row = pg_fetch_array($res);
1221  pg_free_result($res);
1222 
1223  if ($row) {
1224  $result = array(
1225  "type" => "write",
1226  "scope" => $row["exclusivelock"] ? "exclusive" : "shared",
1227  "depth" => 0,
1228  "owner" => $row['owner'],
1229  "token" => $row['token'],
1230  "expires" => $row['expires']
1231  );
1232  }
1233  }
1234  if (!$result) {
1235 
1236  include_once ("FDL/Class.Doc.php");
1237  $fldid = $this->path2id($options["path"], $vid);
1238  $doc = new_doc($this->db_freedom, $fldid);
1239 
1240  if ($doc->isAffected()) {
1241  if ($doc->isLocked(true)) {
1242  $result = array(
1243  "type" => "write",
1244  "scope" => "exclusive",
1245  "depth" => 0,
1246  "owner" => $doc->locked,
1247  "token" => 'opaquelocktoken:' . md5($doc->id) ,
1248  "expires" => time() + 3600
1249  );
1250  error_log("LOCK " . $doc->title);
1251  }
1252  }
1253  }
1254 
1255  return $result;
1256  }
1257  /**
1258  * create database tables for property and lock storage
1259  *
1260  * @param void
1261  * @return bool true on success
1262  */
1263  function create_database()
1264  {
1265  // TODO
1266  return false;
1267  }
1268  /**
1269  * create database tables for property and lock storage
1270  *
1271  * @param void
1272  * @return bool true on success
1273  */
1274  function addsession($sessid, $vid, $docid, $owner, $expire = 0)
1275  {
1276 
1277  $query = "INSERT INTO dav.sessions (session,vid,fid,owner,expires) values (
1278  '$sessid' , $vid , $docid , '$owner' , '$expire')";
1279  $query = sprintf("INSERT INTO dav.sessions (session, vid, fid, owner, expires) values ('%s', %s, %s, '%s', %s)", pg_escape_string($sessid) , pg_escape_string($vid) , pg_escape_string($docid) , pg_escape_string($owner) , pg_escape_string($expire));
1280 
1281  $res = pg_query($this->db_res, $query);
1282 
1283  $err = pg_last_error($this->db_res);
1284  if ($err != "") error_log("$err [$query]");
1285 
1286  if (pg_affected_rows($res)) {
1287  return true;
1288  }
1289  return false;
1290  }
1291  /**
1292  * get login from session
1293  *
1294  * @param void
1295  * @return bool true on success
1296  */
1297  function getLogin($docid, $vid, $sessid)
1298  {
1299 
1300  $query = "select owner from dav.sessions where
1301  session = '$sessid' and
1302  vid = $vid and
1303  fid = $docid";
1304  $query = sprintf("select owner from dav.sessions where session = '%s' and vid = %s and fid = %s", pg_escape_string($sessid) , pg_escape_string($vid) , pg_escape_string($docid));
1305  //error_log("getLogin $query");
1306  $res = pg_query($this->db_res, $query);
1307  $row = pg_fetch_assoc($res);
1308  $owner = $row["owner"];
1309 
1310  pg_free_result($res);
1311 
1312  return $owner;
1313 
1314  return false;
1315  }
1316  /**
1317  * get session from login
1318  *
1319  * @param int $docid document identificator
1320  * @param int $vid vault identificator
1321  * @param string $owner user login
1322  * @return string
1323  */
1324  function getSession($docid, $vid, $owner)
1325  {
1326 
1327  $query = "select session from dav.sessions where
1328  owner = '$owner' and
1329  vid = $vid and
1330  fid = $docid";
1331  $query = sprintf("select session from dav.sessions where owner = '%s' and vid = %s and fid = %s", pg_escape_string($owner) , pg_escape_string($vid) , pg_escape_string($docid));
1332  //error_log("getSession $query");
1333  $res = pg_query($this->db_res, $query);
1334  $row = pg_fetch_assoc($res);
1335  $sid = $row["session"];
1336 
1337  pg_free_result($res);
1338 
1339  return $sid;
1340  }
1341  function mybasename($p)
1342  {
1343  //return basename($p);
1344  $r = strrpos($p, "/");
1345  return ($r !== false) ? substr($p, $r + 1) : $p;
1346  }
1347 
1348  function cleanDeleted($fid)
1349  {
1350  $fid = intval($fid);
1351  $query = sprintf("delete from dav.properties where value='%s' and name= 'fid'", pg_escape_string($fid));
1352 
1353  pg_query($this->db_res, $query);
1354  }
1355  /**
1356  * Set the maximum number of documents returned when listing
1357  * content of a folder
1358  *
1359  * @param int $limit limit value (value < 0 for no limit)
1360  *
1361  * @return int the current limit
1362  */
1363  function setFolderMaxItem($limit)
1364  {
1365  if (!is_numeric($limit) || $limit < 0) {
1366  $limit = 'ALL';
1367  }
1368  $this->folder_max_item = $limit;
1369  return $this->folder_max_item;
1370  }
1371  /**
1372  * Get the currently applied maximum number
1373  *
1374  * @return int the current limit
1375  */
1376  function getFolderMaxItem()
1377  {
1378  if (!is_numeric($this->folder_max_item) || $this->folder_max_item < 0) {
1379  return 'ALL';
1380  }
1381  return $this->folder_max_item;
1382  }
1383 }
1384 ?>
← centre documentaire © anakeen - published under CC License - Dynacase