forked from extern/egroupware
- fixed bug in egw_vfs::check_access for a user different from current one: need to clear the stat-cache after the call too, as the next call might be the regular user again!
- new method egw_vfs::copy_uploaded() to copy a file into vfs and set properties (eg. the comment), while treating the whole operation notification-wise atomar (one notification about an added file). - using that method for egw_link too - fixed egw_link not displaying comments
This commit is contained in:
parent
e6470f6b58
commit
bd7407ed88
@ -961,19 +961,14 @@ class egw_link extends solink
|
||||
}
|
||||
if (file_exists($entry_dir) || ($Ok = mkdir($entry_dir,0,true)))
|
||||
{
|
||||
// use vfs:// url, to ensure vfs_add|modified hook get called
|
||||
$fname = egw_vfs::PREFIX.self::vfs_path($app,$id,egw_vfs::encodePathComponent($file['name']),true);
|
||||
if (($Ok = copy($file['tmp_name'], $fname)) && ($stat = egw_vfs::url_stat($fname, 0)) && $comment)
|
||||
{
|
||||
egw_vfs::proppatch(parse_url($fname,PHP_URL_PATH),array(array('name'=>'comment','val'=>$comment))); // set comment
|
||||
}
|
||||
//error_log(__METHOD__."('$app', '$id', ".array2string($file).", '$comment') called copy('$file[tmp_name]', '$fname')=".array2string($Ok).', stat='.array2string($stat));
|
||||
$Ok = egw_vfs::copy_uploaded($file, $p=self::vfs_path($app,$id,'',true), $comment);
|
||||
error_log(__METHOD__."('$app', '$id', ".array2string($file).", '$comment') called egw_vfs::copy('$file[tmp_name]', '$p')=".array2string($Ok));
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log(__METHOD__."($app,$id,".array2string($file).",$comment) Can't mkdir $entry_dir!");
|
||||
}
|
||||
return $Ok ? -$stat['ino'] : false;
|
||||
return $Ok ? -$Ok['ino'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1094,9 +1089,9 @@ class egw_link extends solink
|
||||
foreach($url2stats as $url => &$fileinfo)
|
||||
{
|
||||
$link = self::fileinfo2link($fileinfo,$url);
|
||||
if (isset($props[$path = parse_url($url,PHP_URL_PATH)]))
|
||||
if ($props && isset($props[$url]))
|
||||
{
|
||||
foreach($props[$path] as $prop)
|
||||
foreach($props[$url] as $prop)
|
||||
{
|
||||
if ($prop['ns'] == egw_vfs::DEFAULT_PROP_NAMESPACE && $prop['name'] == 'comment')
|
||||
{
|
||||
|
@ -181,37 +181,19 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
$ret = false;
|
||||
|
||||
$old_props = self::file_exists($to) ? self::propfind($to,null) : array();
|
||||
// copy properties (eg. file comment), if there are any and evtl. existing old properties
|
||||
$props = self::propfind($from,null);
|
||||
|
||||
if (($from_fp = self::fopen($from,'r')) &&
|
||||
($to_fp = self::fopen($to,'w')))
|
||||
foreach($old_props as $prop)
|
||||
{
|
||||
$ret = stream_copy_to_stream($from_fp,$to_fp) !== false;
|
||||
}
|
||||
if ($from_fp)
|
||||
{
|
||||
fclose($from_fp);
|
||||
}
|
||||
if ($to_fp)
|
||||
{
|
||||
fclose($to_fp);
|
||||
|
||||
if ($ret) // successful copyied file
|
||||
if (!self::find_prop($props,$prop))
|
||||
{
|
||||
// copy properties (eg. file comment), if there are any and evtl. existing old properties
|
||||
$props = self::propfind($from,null);
|
||||
|
||||
foreach($old_props as $prop)
|
||||
{
|
||||
if (!self::find_prop($props,$prop))
|
||||
{
|
||||
$prop['val'] = null; // null = delete prop
|
||||
$props[] = $prop;
|
||||
}
|
||||
}
|
||||
if ($props) self::proppatch($to, $props);
|
||||
$prop['val'] = null; // null = delete prop
|
||||
$props[] = $prop;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
// using self::copy_uploaded() to treat copying incl. properties as atomar operation in respect of notifications
|
||||
return self::copy_uploaded(self::PREFIX.$from,$to,$props,false); // false = no is_uploaded_file check!
|
||||
}
|
||||
|
||||
/**
|
||||
@ -781,6 +763,8 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
self::clearstatcache($path);
|
||||
|
||||
$path_user_stat[$path][$user] = self::url_stat($path, 0);
|
||||
|
||||
self::clearstatcache($path); // we need to clear the stat-cache after the call too, as the next call might be the regular user again!
|
||||
}
|
||||
if (($stat = $path_user_stat[$path][$user]))
|
||||
{
|
||||
@ -1705,6 +1689,64 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy an uploaded file into the vfs, optionally set some properties (eg. comment or other cf's)
|
||||
*
|
||||
* Treat copying incl. properties as atomar operation in respect of notifications (one notification about an added file).
|
||||
*
|
||||
* @param array|string $src path to uploaded file or etemplate file array (value for key 'tmp_name')
|
||||
* @param string $target path or directory to copy uploaded file
|
||||
* @param array|string $props=null array with properties (name => value pairs, eg. 'comment' => 'FooBar','#cfname' => 'something'),
|
||||
* array as for proppatch (array of array with values for keys 'name', 'val' and optional 'ns') or string with comment
|
||||
* @param boolean $check_is_uploaded_file=true should method perform an is_uploaded_file check, default yes
|
||||
* @return boolean|array stat array on success, false on error
|
||||
*/
|
||||
static public function copy_uploaded($src,$target,$props=null,$check_is_uploaded_file=true)
|
||||
{
|
||||
$tmp_name = is_array($src) ? $src['tmp_name'] : $src;
|
||||
|
||||
if (self::stat($target) && self::is_dir($target))
|
||||
{
|
||||
$target = self::concat($target, self::encodePathComponent(is_array($src) ? $src['name'] : basename($tmp_name)));
|
||||
}
|
||||
if ($check_is_uploaded_file && !is_uploaded_file($tmp_name) ||
|
||||
!(self::is_writable($target) || self::is_writable(self::dirname($target))))
|
||||
{
|
||||
if (self::LOG_LEVEL) error_log(__METHOD__."($tmp_name, $target, ".array2string($props).") returning false");
|
||||
return false;
|
||||
}
|
||||
if ($props)
|
||||
{
|
||||
if (!is_array($props)) $props = array(array('name' => 'comment','val' => $props));
|
||||
|
||||
// if $props is name => value pairs, convert it to internal array or array with values for keys 'name', 'val' and optional 'ns'
|
||||
if (!isset($props[0]))
|
||||
{
|
||||
foreach($props as $name => $val)
|
||||
{
|
||||
if (($name == 'comment' || $name[0] == '#') && $val) // only copy 'comment' and cfs
|
||||
{
|
||||
$vfs_props[] = array(
|
||||
'name' => $name,
|
||||
'val' => $val,
|
||||
);
|
||||
}
|
||||
}
|
||||
$props = $vfs_props;
|
||||
}
|
||||
// set props before copying the file, so notifications already contain them
|
||||
if (!self::stat($target))
|
||||
{
|
||||
self::touch($target); // create empty file, to be able to attach properties
|
||||
self::$treat_as_new = true; // notify as new
|
||||
}
|
||||
self::proppatch($target, $props);
|
||||
}
|
||||
$ret = copy($tmp_name,self::PREFIX.$target) ? self::stat($target) : false;
|
||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($tmp_name, $target, ".array2string($props).") returning ".array2string($ret));
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
egw_vfs::init_static();
|
||||
|
@ -255,6 +255,13 @@ class vfs_stream_wrapper implements iface_stream_wrapper
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used from egw_vfs to tell vfs notifications to treat an opened file as a new file
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
static protected $treat_as_new;
|
||||
|
||||
/**
|
||||
* This method is called immediately after your stream object is created.
|
||||
*
|
||||
@ -284,6 +291,13 @@ class vfs_stream_wrapper implements iface_stream_wrapper
|
||||
$this->opened_stream_url = $url;
|
||||
$this->opened_stream_is_new = !$stat;
|
||||
|
||||
// are we requested to treat the opened file as new file (only for files opened NOT for reading)
|
||||
if ($mode[0] != 'r' && !$this->opened_stream_is_new && self::$treat_as_new)
|
||||
{
|
||||
$this->opened_stream_is_new = true;
|
||||
//error_log(__METHOD__."($path,$mode,...) stat=$stat, treat_as_new=".self::$treat_as_new." --> ".array2string($this->opened_stream_is_new));
|
||||
self::$treat_as_new = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user