diff --git a/phpgwapi/inc/class.egw_vfs.inc.php b/phpgwapi/inc/class.egw_vfs.inc.php index 45c6bfc039..de7b2d5421 100644 --- a/phpgwapi/inc/class.egw_vfs.inc.php +++ b/phpgwapi/inc/class.egw_vfs.inc.php @@ -1167,6 +1167,10 @@ class egw_vfs extends vfs_stream_wrapper */ static function download_url($path,$force_download=false) { + if (($url = self::_call_on_backend('download_url',array($path,$force_download),true))) + { + return $url; + } if ($path[0] != '/') { $path = parse_url($path,PHP_URL_PATH); diff --git a/phpgwapi/inc/class.filesystem_stream_wrapper.inc.php b/phpgwapi/inc/class.filesystem_stream_wrapper.inc.php index 2e7c77327b..c01706fa25 100644 --- a/phpgwapi/inc/class.filesystem_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.filesystem_stream_wrapper.inc.php @@ -23,6 +23,8 @@ * - mode: mode bit for the path, default 0005 (read and execute for nobody) * - exec: false (default) = do NOT allow to upload or modify scripts, true = allow it (if docroot is mounted, this allows to run scripts!) * scripts are considered every file having a script-extension (eg. .php, .pl, .py), defined with SCRIPT_EXTENSION_PREG constant + * - url: download url, if NOT a regular webdav.php download should be used, eg. because directory already + * lies within the docroot or is mapped via an alias * * To correctly support characters with special meaning in url's (#?%), we urlencode them with egw_vfs::encodePathComponent * and urldecode all path again, before passing them to php's filesystem functions. @@ -683,6 +685,9 @@ class filesystem_stream_wrapper implements iface_stream_wrapper case 'mode': $mode = egw_vfs::mode2int($value); break; + case 'url': + // ignored, only used for download_url method + break; default: error_log(__METHOD__."('$query') unknown option '$name'!"); break; @@ -711,6 +716,40 @@ class filesystem_stream_wrapper implements iface_stream_wrapper } return $deny; } + + /** + * URL to download a file + * + * We use our webdav handler as download url instead of an own download method. + * The webdav hander (filemanager/webdav.php) recognices eGW's session cookie and of cause understands regular GET requests. + * + * @param string $url + * @param boolean $force_download=false add header('Content-disposition: filename="' . basename($path) . '"'), currently not supported! + * @todo get $force_download working through webdav + * @return string|false string with full download url or false to use default webdav.php url + */ + static function download_url($url,$force_download=false) + { + list(,$query) = explode('?',$url,2); + parse_str($query,$get); + if (empty($get['url'])) return false; // no download url given for this mount-point + + if (!($mount_url = egw_vfs::mount_url($url))) return false; // no mount url found, should not happen + list($mount_url) = explode('?',$mount_url); + + list($url,$query) = explode('?',$url,2); + $relpath = substr($url,strlen($mount_url)); + + $download_url = egw_vfs::concat($get['url'],$relpath); + if ($download_url[0] == '/') + { + $download_url = ($_SERVER['HTTPS'] ? 'https://' : 'http://'). + $_SERVER['HTTP_HOST'].$download_url; + } + + //die(__METHOD__."('$url') --> relpath = $relpath --> $download_url"); + return $download_url; + } } stream_register_wrapper(filesystem_stream_wrapper::SCHEME ,'filesystem_stream_wrapper'); diff --git a/phpgwapi/inc/class.vfs_stream_wrapper.inc.php b/phpgwapi/inc/class.vfs_stream_wrapper.inc.php index 9f0b5ea1a2..eafb84059f 100644 --- a/phpgwapi/inc/class.vfs_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.vfs_stream_wrapper.inc.php @@ -201,6 +201,25 @@ class vfs_stream_wrapper implements iface_stream_wrapper trigger_error(__METHOD__."($path) can't resolve path!\n",E_USER_WARNING); return false; } + + /** + * Returns mount url of a full url returned by resolve_url + * + * @param string $fullurl full url returned by resolve_url + * @return string|NULL mount url or null if not found + */ + static function mount_url($fullurl) + { + foreach(array_reverse(self::$fstab) as $mounted => $url) + { + list($url_no_query) = explode('?',$url); + if (substr($fullurl,0,1+strlen($url_no_query)) === $url_no_query.'/') + { + return $url; + } + } + return null; + } /** * This method is called immediately after your stream object is created.