- 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)
This commit is contained in:
Ralf Becker 2009-12-01 14:51:13 +00:00
parent 868e9b7356
commit b59a688fbb
4 changed files with 62 additions and 24 deletions

View File

@ -10,6 +10,9 @@
* @version $Id$ * @version $Id$
*/ */
/**
* Filemanage user interface class
*/
class filemanager_ui class filemanager_ui
{ {
/** /**
@ -80,7 +83,7 @@ class filemanager_ui
if (!is_array($content)) if (!is_array($content))
{ {
$content = array( $content = array(
'nm' => $GLOBALS['egw']->session->appsession('index','filemanager'), 'nm' => egw_session::appsession('index','filemanager'),
); );
if (!is_array($content['nm'])) if (!is_array($content['nm']))
{ {
@ -152,8 +155,8 @@ class filemanager_ui
} }
unset($content['nm']['rows']); unset($content['nm']['rows']);
} }
$clipboard_files = $GLOBALS['egw']->session->appsession('clipboard_files','filemanager'); $clipboard_files = egw_session::appsession('clipboard_files','filemanager');
$clipboard_type = $GLOBALS['egw']->session->appsession('clipboard_type','filemanager'); $clipboard_type = egw_session::appsession('clipboard_type','filemanager');
if ($content['button']) if ($content['button'])
{ {
@ -178,7 +181,7 @@ class filemanager_ui
case 'createdir': case 'createdir':
if ($content['nm']['path'][0] != '/') if ($content['nm']['path'][0] != '/')
{ {
$ses = $GLOBALS['egw']->session->appsession('index','filemanager'); $ses = egw_session::appsession('index','filemanager');
$old_path = $ses['path']; $old_path = $ses['path'];
$content['nm']['path'] = egw_vfs::concat($old_path,$content['nm']['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!'); lang('Permission denied!') : lang('Failed to create directory!');
if (!$old_path) if (!$old_path)
{ {
$ses = $GLOBALS['egw']->session->appsession('index','filemanager'); $ses = egw_session::appsession('index','filemanager');
$old_path = $ses['path']; $old_path = $ses['path'];
} }
$content['nm']['path'] = $old_path; $content['nm']['path'] = $old_path;
@ -196,7 +199,7 @@ class filemanager_ui
break; break;
case 'symlink': case 'symlink':
$target = $content['nm']['path']; $target = $content['nm']['path'];
$ses = $GLOBALS['egw']->session->appsession('index','filemanager'); $ses = egw_session::appsession('index','filemanager');
$content['nm']['path'] = $ses['path']; $content['nm']['path'] = $ses['path'];
$link = egw_vfs::concat($content['nm']['path'],egw_vfs::basename($target)); $link = egw_vfs::concat($content['nm']['path'],egw_vfs::basename($target));
$abs_target = $target[0] == '/' ? $target : egw_vfs::concat($content['nm']['path'],$target); $abs_target = $target[0] == '/' ? $target : egw_vfs::concat($content['nm']['path'],$target);
@ -463,8 +466,8 @@ class filemanager_ui
case 'copy': case 'copy':
case 'cut': case 'cut':
$GLOBALS['egw']->session->appsession('clipboard_files','filemanager',$selected); egw_session::appsession('clipboard_files','filemanager',$selected);
$GLOBALS['egw']->session->appsession('clipboard_type','filemanager',$action); egw_session::appsession('clipboard_type','filemanager',$action);
return lang('%1 URLs %2 to clipboard.',count($selected),$action=='copy'?lang('copied'):lang('cut')); return lang('%1 URLs %2 to clipboard.',count($selected),$action=='copy'?lang('copied'):lang('cut'));
case 'copy_paste': case 'copy_paste':
@ -527,7 +530,7 @@ class filemanager_ui
++$errs; ++$errs;
} }
} }
$GLOBALS['egw']->session->appsession('clipboard_files','filemanager',false); // cant move again egw_session::appsession('clipboard_files','filemanager',false); // cant move again
if ($errs) if ($errs)
{ {
return lang('%1 errors moving (%2 files moved)!',$errs,$files); 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_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)) 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['path'] = $path;
$content['hsize'] = egw_vfs::hsize($stat['size']); $content['hsize'] = egw_vfs::hsize($stat['size']);
$content['mime'] = egw_vfs::mime_content_type($path); $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 $content['gid'] *= -1; // our widgets use negative gid's
if (($props = egw_vfs::propfind($path))) if (($props = egw_vfs::propfind($path)))
{ {
@ -759,6 +761,7 @@ class filemanager_ui
$msg .= lang('Renamed %1 to %2.',basename($path),basename($to)).' '; $msg .= lang('Renamed %1 to %2.',basename($path),basename($to)).' ';
$content['old']['name'] = $content[$name]; $content['old']['name'] = $content[$name];
$path = $to; $path = $to;
$content['mime'] = mime_magic::filename2mime($path); // recheck mime type
} }
else else
{ {
@ -869,13 +872,14 @@ class filemanager_ui
$js = "opener.location.href='".addslashes($link)."'; "; $js = "opener.location.href='".addslashes($link)."'; ";
if ($button == 'save') $js .= "window.close();"; if ($button == 'save') $js .= "window.close();";
echo "<html>\n<body>\n<script>\n$js\n</script>\n</body>\n</html>\n"; echo "<html>\n<body>\n<script>\n$js\n</script>\n</body>\n</html>\n";
if ($button == 'save')$GLOBALS['egw']->common->egw_exit(); if ($button == 'save') common::egw_exit();
} }
if ($content['is_link'] && !egw_vfs::stat($path)) if ($content['is_link'] && !egw_vfs::stat($path))
{ {
$msg .= ($msg ? "\n" : '').lang('Link target %1 not found!',$content['symlink']); $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; $content['msg'] = $msg;
if (($readonlys['uid'] = !egw_vfs::$is_root) && !$content['uid']) $content['ro_uid_root'] = 'root'; if (($readonlys['uid'] = !egw_vfs::$is_root) && !$content['uid']) $content['ro_uid_root'] = 'root';

View File

@ -206,6 +206,21 @@ class links_stream_wrapper extends sqlfs_stream_wrapper
return parent::stream_open($url,$mode,$options,$opened_path); 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'); stream_register_wrapper(links_stream_wrapper::SCHEME ,'links_stream_wrapper');

View File

@ -538,9 +538,11 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
* *
* @param string $url_from * @param string $url_from
* @param string $url_to * @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 * @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)"); 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); $to_dir = dirname($path_to);
$operation = self::url2operation($url_from); $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_from);
self::_remove_password($url_to); self::_remove_password($url_to);
if (self::LOG_LEVEL) error_log(__METHOD__."($url_from,$url_to): $path_from permission denied!"); if (self::LOG_LEVEL) error_log(__METHOD__."($url_from,$url_to): $path_from permission denied!");
return false; // no permission or file does not exist 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_from);
self::_remove_password($url_to); 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 // 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 // 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)) ($to_stat['mime'] === self::DIR_MIME_TYPE) !== ($from_stat['mime'] === self::DIR_MIME_TYPE))
{ {
self::_remove_password($url_from); 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 return false; // no permission or file does not exist
} }
// if destination file already exists, delete it // 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); self::_remove_password($url_to);
if (self::LOG_LEVEL) error_log(__METHOD__."($url_to,$url_from) can't unlink existing $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]); 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'); $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_dir' => $to_dir_stat['ino'],
'fs_name' => egw_vfs::basename($path_to), 'fs_name' => egw_vfs::basename($path_to),
'fs_id' => $from_stat['ino'], '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 "<p>egw_vfs::nime_content_type($url_to,true) = $new_mime</p>\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;
} }
/** /**

View File

@ -611,19 +611,20 @@ class vfs_stream_wrapper implements iface_stream_wrapper
* - use eGW's mime-magic class * - use eGW's mime-magic class
* *
* @param string $path * @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) * @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))) if (!($url = self::resolve_url_symlinks($path)))
{ {
return false; 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 // 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 // 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') && defined($class.'::STAT_RETURN_MIME_TYPE') &&
($mime_attr = constant($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); $mime = mime_content_type($path);
} }
// using eGW's own mime magic // using EGw's own mime magic (currently only checking the extension!)
if (!$mime) if (!$mime)
{ {
$mime = mime_magic::filename2mime(parse_url($url,PHP_URL_PATH)); $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; return $mime;
} }