From 401c0de336ec2073674e7ace0b26bfe683df3756 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Sun, 5 Oct 2008 19:01:49 +0000 Subject: [PATCH] - renamed key of property value to 'val' like in HTTP_WebDAV_Server - support for propfind and proppatch for WebDAV --- filemanager/inc/class.filemanager_ui.inc.php | 10 +-- phpgwapi/inc/class.egw_vfs.inc.php | 4 +- .../inc/class.sqlfs_stream_wrapper.inc.php | 15 ++-- phpgwapi/inc/class.vfs_webdav_server.inc.php | 74 +++++++++++++++---- 4 files changed, 75 insertions(+), 28 deletions(-) diff --git a/filemanager/inc/class.filemanager_ui.inc.php b/filemanager/inc/class.filemanager_ui.inc.php index f28e2913b8..a00dc6523e 100644 --- a/filemanager/inc/class.filemanager_ui.inc.php +++ b/filemanager/inc/class.filemanager_ui.inc.php @@ -521,7 +521,7 @@ class filemanager_ui $cfs = config::get_customfields('filemanager'); $all_cfs = in_array('customfields',$cols_to_show) && $cols_to_show[count($cols_to_show)-1][0] != '#'; if ($path2n && (in_array('comment',$cols_to_show) || in_array('customfields',$cols_to_show)) && - ($path2props = egw_vfs::propfind(array_keys($path2n),'http://egroupware.org/'))) + ($path2props = egw_vfs::propfind(array_keys($path2n)))) { foreach($path2props as $path => $props) { @@ -529,7 +529,7 @@ class filemanager_ui foreach($props as $prop) { if (!$all_cfs && $prop['name'][0] == '#' && !in_array($prop['name'],$cols_to_show)) continue; - $row[$prop['name']] = strlen($prop['value']) < 64 ? $prop['value'] : substr($prop['value'],0,64).' ...'; + $row[$prop['name']] = strlen($prop['val']) < 64 ? $prop['val'] : substr($prop['val'],0,64).' ...'; } } } @@ -567,7 +567,7 @@ class filemanager_ui $content['gid'] *= -1; // our widgets use negative gid's if (($props = egw_vfs::propfind($path))) { - foreach($props as $prop) $content[$prop['name']] = $prop['value']; + foreach($props as $prop) $content[$prop['name']] = $prop['val']; } } $content[$tabs] = $_GET['tabs']; @@ -619,7 +619,7 @@ class filemanager_ui } elseif ($name[0] == '#' || $name == 'comment') { - $props[] = array('name' => $name, 'value' => $content[$name] ? $content[$name] : null); + $props[] = array('name' => $name, 'val' => $content[$name] ? $content[$name] : null); } else { @@ -649,7 +649,7 @@ class filemanager_ui { foreach($props as $prop) { - $content['old'][$prop['name']] = $prop['value']; + $content['old'][$prop['name']] = $prop['val']; } $msg .= lang('Properties saved.'); } diff --git a/phpgwapi/inc/class.egw_vfs.inc.php b/phpgwapi/inc/class.egw_vfs.inc.php index 518b458715..0d53a71129 100644 --- a/phpgwapi/inc/class.egw_vfs.inc.php +++ b/phpgwapi/inc/class.egw_vfs.inc.php @@ -693,7 +693,7 @@ class egw_vfs extends vfs_stream_wrapper * Store properties for a single ressource (file or dir) * * @param string $path string with path - * @param array $props array or array with values for keys 'name', 'ns', 'value' (null to delete the prop) + * @param array $props array or array with values for keys 'name', 'ns', 'val' (null to delete the prop) * @return boolean true if props are updated, false otherwise (eg. ressource not found) */ static function proppatch($path,array $props) @@ -712,7 +712,7 @@ class egw_vfs extends vfs_stream_wrapper * * @param array|string $path (array of) string with path * @param string $ns='http://egroupware.org/' namespace if propfind should be limited to a single one, otherwise use null - * @return array|boolean array with props (values for keys 'name', 'ns', 'value'), or path => array of props for is_array($path) + * @return array|boolean array with props (values for keys 'name', 'ns', 'val'), or path => array of props for is_array($path) * false if $path does not exist */ static function propfind($path,$ns=self::DEFAULT_PROP_NAMESPACE) diff --git a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php index 40728ee180..1ddc81df0d 100644 --- a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php @@ -1503,11 +1503,12 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper * Store properties for a single ressource (file or dir) * * @param string|int $path string with path or integer fs_id - * @param array $props array or array with values for keys 'name', 'ns', 'value' (null to delete the prop) + * @param array $props array or array with values for keys 'name', 'ns', 'val' (null to delete the prop) * @return boolean true if props are updated, false otherwise (eg. ressource not found) */ static function proppatch($path,array &$props) { + //error_log(__METHOD__."(".array2string($path).','.array2string($props)); if (!is_numeric($path)) { if (!($stat = self::url_stat($path,0))) @@ -1528,7 +1529,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper { if (!isset($prop['ns'])) $prop['ns'] = egw_vfs::DEFAULT_PROP_NAMESPACE; - if (!isset($prop['value']) || self::$pdo_type != 'mysql') // for non mysql, we have to delete the prop anyway, as there's no REPLACE! + if (!isset($prop['val']) || self::$pdo_type != 'mysql') // for non mysql, we have to delete the prop anyway, as there's no REPLACE! { if (!isset($del_stmt)) { @@ -1539,7 +1540,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper $del_stmt->bindParam(':prop_name',$prop['name']); $del_stmt->execute(); } - if (isset($prop['value'])) + if (isset($prop['val'])) { if (!isset($ins_stmt)) { @@ -1549,7 +1550,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper } $ins_stmt->bindParam(':prop_namespace',$prop['ns']); $ins_stmt->bindParam(':prop_name',$prop['name']); - $ins_stmt->bindParam(':prop_value',$prop['value']); + $ins_stmt->bindParam(':prop_value',$prop['val']); if (!$ins_stmt->execute()) { return false; @@ -1595,9 +1596,9 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper foreach($stmt as $row) { $props[$row['fs_id']][] = array( - 'value' => $row['prop_value'], - 'name' => $row['prop_name'], - 'ns' => $row['prop_namespace'], + 'val' => $row['prop_value'], + 'name' => $row['prop_name'], + 'ns' => $row['prop_namespace'], ); } if (!is_array($path_ids)) diff --git a/phpgwapi/inc/class.vfs_webdav_server.inc.php b/phpgwapi/inc/class.vfs_webdav_server.inc.php index 848f50f837..15719c2d37 100644 --- a/phpgwapi/inc/class.vfs_webdav_server.inc.php +++ b/phpgwapi/inc/class.vfs_webdav_server.inc.php @@ -169,22 +169,57 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem */ // ToDo: etag from inode and modification time -/* - // get additional properties from database - $query = "SELECT ns, name, value - FROM {$this->db_prefix}properties - WHERE path = '$path'"; - $res = mysql_query($query); - while ($row = mysql_fetch_assoc($res)) { - $info["props"][] = HTTP_WebDAV_Server::mkprop ($row["ns"], $row["name"], $row["value"]); - } - mysql_free_result($res); -*/ //error_log(__METHOD__."($path) info=".print_r($info,true)); return $info; } /** + * PROPFIND method handler + * + * Reimplemented to fetch all extra property of a PROPFIND request in one go. + * + * @param array general parameter passing array + * @param array return array for file properties + * @return bool true on success + */ + function PROPFIND(&$options, &$files) + { + if (!parent::PROPFIND($options,$files)) + { + return false; + } + $path2n = array(); + foreach($files['files'] as $n => $info) + { + if (!$n && substr($info['path'],-1) == '/') + { + $path2n[substr($info['path'],0,-1)] = $n; + } + else + { + $path2n[$info['path']] = $n; + } + } + if ($path2n && ($path2props = egw_vfs::propfind(array_keys($path2n),null))) + { + foreach($path2props as $path => $props) + { + $fileprops =& $files['files'][$path2n[$path]]['props']; + foreach($props as $prop) + { + if ($prop['ns'] == egw_vfs::DEFAULT_PROP_NAMESPACE && $prop['name'][0] == '#') // eGW's customfields + { + $prop['ns'] .= 'customfields/'; + $prop['name'] = substr($prop['name'],1); + } + $fileprops[] = $prop; + } + } + } + return true; + } + + /** * Used eg. by get * * @todo replace all calls to _mimetype with egw_vfs::mime_content_type() @@ -223,9 +258,12 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem case 'getlastmodified': egw_vfs::touch($path,strtotime($prop['val'])); break; - case 'srt_creationtime': + //case 'srt_creationtime': // not supported via the streamwrapper interface atm. //$attributes['created'] = strtotime($prop['val']); + //break; + default: + if (!egw_vfs::proppatch($path,array($prop))) $options['props'][$key]['status'] = '403 Forbidden'; break; } break; @@ -243,6 +281,14 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem break; } break; + + case egw_vfs::DEFAULT_PROP_NAMESPACE.'customfields/': // eGW's customfields + $prop['ns'] = egw_vfs::DEFAULT_PROP_NAMESPACE; + $prop['name'] = '#'.$prop['name']; + // fall through + default: + if (!egw_vfs::proppatch($path,array($prop))) $options['props'][$key]['status'] = '403 Forbidden'; + break; } if ($this->debug) $props[] = '('.$prop['ns'].')'.$prop['name'].'='.$prop['val']; } @@ -263,7 +309,7 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem */ function LOCK(&$options) { - error_log(__METHOD__.'('.str_replace(array("\n",' '),'',print_r($options,true)).')'); + if ($this->debug) error_log(__METHOD__.'('.str_replace(array("\n",' '),'',print_r($options,true)).')'); // TODO recursive locks on directories not supported yet if (is_dir($this->base . $options['path']) && !empty($options['depth'])) { @@ -289,7 +335,7 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem */ function UNLOCK(&$options) { - error_log(__METHOD__.'('.str_replace(array("\n",' '),'',print_r($options,true)).')'); + if ($this->debug) error_log(__METHOD__.'('.str_replace(array("\n",' '),'',print_r($options,true)).')'); return egw_vfs::unlock($options['path'],$options['token']) ? '204 No Content' : '409 Conflict'; }