From b59a688fbb0edf34025f610ecc6a7cace26fb889 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Tue, 1 Dec 2009 14:51:13 +0000 Subject: [PATCH] - fixed not working rename in entry directories in /apps (eg. rename of an infolog attachment), was caused by use of url_stat from sqlfs instead of links stream wrapper - fixed wrong mime type / icon in files stored via netdrive from msword (the first use the extension .tmp, before renaming file to .doc: sqlfs "detects" mime type only from the extension and did not recheck it if a file gets renamed, that's now fixed) --- filemanager/inc/class.filemanager_ui.inc.php | 30 +++++++++++-------- .../inc/class.links_stream_wrapper.inc.php | 15 ++++++++++ .../inc/class.sqlfs_stream_wrapper.inc.php | 30 +++++++++++++++---- phpgwapi/inc/class.vfs_stream_wrapper.inc.php | 11 +++---- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/filemanager/inc/class.filemanager_ui.inc.php b/filemanager/inc/class.filemanager_ui.inc.php index b39b341550..f3a529e8cd 100644 --- a/filemanager/inc/class.filemanager_ui.inc.php +++ b/filemanager/inc/class.filemanager_ui.inc.php @@ -10,6 +10,9 @@ * @version $Id$ */ +/** + * Filemanage user interface class + */ class filemanager_ui { /** @@ -80,7 +83,7 @@ class filemanager_ui if (!is_array($content)) { $content = array( - 'nm' => $GLOBALS['egw']->session->appsession('index','filemanager'), + 'nm' => egw_session::appsession('index','filemanager'), ); if (!is_array($content['nm'])) { @@ -152,8 +155,8 @@ class filemanager_ui } unset($content['nm']['rows']); } - $clipboard_files = $GLOBALS['egw']->session->appsession('clipboard_files','filemanager'); - $clipboard_type = $GLOBALS['egw']->session->appsession('clipboard_type','filemanager'); + $clipboard_files = egw_session::appsession('clipboard_files','filemanager'); + $clipboard_type = egw_session::appsession('clipboard_type','filemanager'); if ($content['button']) { @@ -178,7 +181,7 @@ class filemanager_ui case 'createdir': if ($content['nm']['path'][0] != '/') { - $ses = $GLOBALS['egw']->session->appsession('index','filemanager'); + $ses = egw_session::appsession('index','filemanager'); $old_path = $ses['path']; $content['nm']['path'] = egw_vfs::concat($old_path,$content['nm']['path']); } @@ -188,7 +191,7 @@ class filemanager_ui lang('Permission denied!') : lang('Failed to create directory!'); if (!$old_path) { - $ses = $GLOBALS['egw']->session->appsession('index','filemanager'); + $ses = egw_session::appsession('index','filemanager'); $old_path = $ses['path']; } $content['nm']['path'] = $old_path; @@ -196,7 +199,7 @@ class filemanager_ui break; case 'symlink': $target = $content['nm']['path']; - $ses = $GLOBALS['egw']->session->appsession('index','filemanager'); + $ses = egw_session::appsession('index','filemanager'); $content['nm']['path'] = $ses['path']; $link = egw_vfs::concat($content['nm']['path'],egw_vfs::basename($target)); $abs_target = $target[0] == '/' ? $target : egw_vfs::concat($content['nm']['path'],$target); @@ -463,8 +466,8 @@ class filemanager_ui case 'copy': case 'cut': - $GLOBALS['egw']->session->appsession('clipboard_files','filemanager',$selected); - $GLOBALS['egw']->session->appsession('clipboard_type','filemanager',$action); + egw_session::appsession('clipboard_files','filemanager',$selected); + egw_session::appsession('clipboard_type','filemanager',$action); return lang('%1 URLs %2 to clipboard.',count($selected),$action=='copy'?lang('copied'):lang('cut')); case 'copy_paste': @@ -527,7 +530,7 @@ class filemanager_ui ++$errs; } } - $GLOBALS['egw']->session->appsession('clipboard_files','filemanager',false); // cant move again + egw_session::appsession('clipboard_files','filemanager',false); // cant move again if ($errs) { return lang('%1 errors moving (%2 files moved)!',$errs,$files); @@ -571,7 +574,7 @@ class filemanager_ui { $GLOBALS['egw_info']['flags']['currentapp'] = 'projectmanager'; } - $GLOBALS['egw']->session->appsession('index','filemanager',$query); + egw_session::appsession('index','filemanager',$query); if (!egw_vfs::stat($query['path'],true) || !egw_vfs::is_dir($query['path']) || !egw_vfs::check_access($query['path'],egw_vfs::READABLE)) { @@ -688,7 +691,6 @@ class filemanager_ui $content['path'] = $path; $content['hsize'] = egw_vfs::hsize($stat['size']); $content['mime'] = egw_vfs::mime_content_type($path); - $content['icon'] = egw_vfs::mime_icon($content['mime']); $content['gid'] *= -1; // our widgets use negative gid's if (($props = egw_vfs::propfind($path))) { @@ -759,6 +761,7 @@ class filemanager_ui $msg .= lang('Renamed %1 to %2.',basename($path),basename($to)).' '; $content['old']['name'] = $content[$name]; $path = $to; + $content['mime'] = mime_magic::filename2mime($path); // recheck mime type } else { @@ -869,13 +872,14 @@ class filemanager_ui $js = "opener.location.href='".addslashes($link)."'; "; if ($button == 'save') $js .= "window.close();"; echo "\n\n\n\n\n"; - if ($button == 'save')$GLOBALS['egw']->common->egw_exit(); + if ($button == 'save') common::egw_exit(); } if ($content['is_link'] && !egw_vfs::stat($path)) { $msg .= ($msg ? "\n" : '').lang('Link target %1 not found!',$content['symlink']); } - $content['link'] = $GLOBALS['egw']->link(egw_vfs::download_url($path)); + $content['link'] = egw::link(egw_vfs::download_url($path)); + $content['icon'] = egw_vfs::mime_icon($content['mime']); $content['msg'] = $msg; if (($readonlys['uid'] = !egw_vfs::$is_root) && !$content['uid']) $content['ro_uid_root'] = 'root'; diff --git a/phpgwapi/inc/class.links_stream_wrapper.inc.php b/phpgwapi/inc/class.links_stream_wrapper.inc.php index db755c5e0e..fc538568b4 100644 --- a/phpgwapi/inc/class.links_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.links_stream_wrapper.inc.php @@ -206,6 +206,21 @@ class links_stream_wrapper extends sqlfs_stream_wrapper return parent::stream_open($url,$mode,$options,$opened_path); } + + /** + * This method is called in response to rename() calls on URL paths associated with the wrapper. + * + * Reimplemented to use our own url_stat and unlink function (workaround for no lsb in php < 5.3) + * + * @param string $url_from + * @param string $url_to + * @param string $class=__CLASS__ class to use to call static methods, eg url_stat (workaround for no late static binding in php < 5.3) + * @return boolean TRUE on success or FALSE on failure + */ + static function rename ( $url_from, $url_to, $class=__CLASS__) + { + return parent::rename($url_from,$url_to,$class); + } } stream_register_wrapper(links_stream_wrapper::SCHEME ,'links_stream_wrapper'); diff --git a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php index 480cbe8318..dbef43847a 100644 --- a/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.sqlfs_stream_wrapper.inc.php @@ -538,9 +538,11 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper * * @param string $url_from * @param string $url_to + * @param string $class=__CLASS__ class to use to call static methods, eg url_stat (workaround for no late static binding in php < 5.3) + * @todo remove $class parameter and use static::url_stat() and static::unlink() once we require PHP5.3! * @return boolean TRUE on success or FALSE on failure */ - static function rename ( $url_from, $url_to ) + static function rename ( $url_from, $url_to, $class=__CLASS__) { if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url_from,$url_to)"); @@ -549,14 +551,15 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper $to_dir = dirname($path_to); $operation = self::url2operation($url_from); - if (!($from_stat = self::url_stat($path_from,0)) || !egw_vfs::check_access(dirname($path_from),egw_vfs::WRITABLE)) + // we have to use array($class,'url_stat'), as $class.'::url_stat' requires PHP 5.2.3 and we currently only require 5.2+ + if (!($from_stat = call_user_func(array($class,'url_stat'),$path_from,0)) || !egw_vfs::check_access(dirname($path_from),egw_vfs::WRITABLE)) { self::_remove_password($url_from); self::_remove_password($url_to); if (self::LOG_LEVEL) error_log(__METHOD__."($url_from,$url_to): $path_from permission denied!"); return false; // no permission or file does not exist } - if (!egw_vfs::check_access($to_dir,egw_vfs::WRITABLE,$to_dir_stat = self::url_stat($to_dir,0))) + if (!egw_vfs::check_access($to_dir,egw_vfs::WRITABLE,$to_dir_stat = call_user_func(array($class,'url_stat'),$to_dir,0))) { self::_remove_password($url_from); self::_remove_password($url_to); @@ -565,7 +568,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper } // the filesystem stream-wrapper does NOT allow to rename files to directories, as this makes problems // for our vfs too, we abort here with an error, like the filesystem one does - if (($to_stat = self::url_stat($path_to,0)) && + if (($to_stat = call_user_func(array($class,'url_stat'),$path_to,0)) && ($to_stat['mime'] === self::DIR_MIME_TYPE) !== ($from_stat['mime'] === self::DIR_MIME_TYPE)) { self::_remove_password($url_from); @@ -575,7 +578,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper return false; // no permission or file does not exist } // if destination file already exists, delete it - if ($to_stat && !self::unlink($url_to,$operation)) + if ($to_stat && !call_user_func(array($class,'unlink'),$url_to,$operation)) { self::_remove_password($url_to); if (self::LOG_LEVEL) error_log(__METHOD__."($url_to,$url_from) can't unlink existing $url_to!"); @@ -585,11 +588,26 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper unset(self::$stat_cache[$path_to]); $stmt = self::$pdo->prepare('UPDATE '.self::TABLE.' SET fs_dir=:fs_dir,fs_name=:fs_name WHERE fs_id=:fs_id'); - return $stmt->execute(array( + $ok = $stmt->execute(array( 'fs_dir' => $to_dir_stat['ino'], 'fs_name' => egw_vfs::basename($path_to), 'fs_id' => $from_stat['ino'], )); + unset($stmt); + + // check if extension changed and update mime-type in that case (as we currently determine mime-type by it's extension!) + // fixes eg. problems with MsWord storing file with .tmp extension and then renaming to .doc + if ($ok && ($new_mime = egw_vfs::mime_content_type($url_to,true)) != egw_vfs::mime_content_type($url_to)) + { + //echo "

egw_vfs::nime_content_type($url_to,true) = $new_mime

\n"; + $stmt = self::$pdo->prepare('UPDATE '.self::TABLE.' SET fs_mime=:fs_mime WHERE fs_id=:fs_id'); + $stmt->execute(array( + 'fs_mime' => $new_mime, + 'fs_id' => $from_stat['ino'], + )); + unset(self::$stat_cache[$path_to]); + } + return $ok; } /** diff --git a/phpgwapi/inc/class.vfs_stream_wrapper.inc.php b/phpgwapi/inc/class.vfs_stream_wrapper.inc.php index 24e6f862ca..e6f836ffec 100644 --- a/phpgwapi/inc/class.vfs_stream_wrapper.inc.php +++ b/phpgwapi/inc/class.vfs_stream_wrapper.inc.php @@ -611,19 +611,20 @@ class vfs_stream_wrapper implements iface_stream_wrapper * - use eGW's mime-magic class * * @param string $path + * @param boolean $recheck=false true = do a new check, false = rely on stored mime type (if existing) * @return string mime-type (self::DIR_MIME_TYPE for directories) */ - static function mime_content_type($path) + static function mime_content_type($path,$recheck=false) { if (!($url = self::resolve_url_symlinks($path))) { return false; } - if (($scheme = parse_url($url,PHP_URL_SCHEME))) + if (($scheme = parse_url($url,PHP_URL_SCHEME)) && !$recheck) { // check it it's an eGW stream wrapper returning mime-type via url_stat // we need to first check if the constant is defined, as we get a fatal error in php5.3 otherwise - if (class_exists($class = self::scheme2class($scheme)) && + if (class_exists($class = self::scheme2class($scheme)) && defined($class.'::STAT_RETURN_MIME_TYPE') && ($mime_attr = constant($class.'::STAT_RETURN_MIME_TYPE'))) { @@ -643,12 +644,12 @@ class vfs_stream_wrapper implements iface_stream_wrapper { $mime = mime_content_type($path); } - // using eGW's own mime magic + // using EGw's own mime magic (currently only checking the extension!) if (!$mime) { $mime = mime_magic::filename2mime(parse_url($url,PHP_URL_PATH)); } - //error_log(__METHOD__."($path) mime=$mime"); + //error_log(__METHOD__."($path,$recheck) mime=$mime"); return $mime; }