* Filemanager: add ability to finally delete all old versions or deleted files from a versioned directory

This commit is contained in:
Ralf Becker 2016-01-21 11:49:50 +00:00
parent a7a82f7200
commit 29c73a8694
8 changed files with 141 additions and 63 deletions

View File

@ -7,7 +7,7 @@
* @package api * @package api
* @subpackage vfs * @subpackage vfs
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2008-15 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2008-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$ * @version $Id$
*/ */
@ -423,13 +423,14 @@ class Vfs extends Vfs\StreamWrapper
* Check if file is hidden: name starts with a '.' or is Thumbs.db * Check if file is hidden: name starts with a '.' or is Thumbs.db
* *
* @param string $path * @param string $path
* @param boolean $allow_versions =false allow .versions or .attic
* @return boolean * @return boolean
*/ */
public static function is_hidden($path) public static function is_hidden($path, $allow_versions=false)
{ {
$file = self::basename($path); $file = self::basename($path);
return $file[0] == '.' || $file == 'Thumbs.db'; return $file[0] == '.' && (!$allow_versions || !in_array($file, array('.versions', '.attic'))) || $file == 'Thumbs.db';
} }
/** /**
@ -455,6 +456,7 @@ class Vfs extends Vfs\StreamWrapper
* - limit => N,[n=0] return N entries from position n on, which defaults to 0 * - limit => N,[n=0] return N entries from position n on, which defaults to 0
* - follow => {true|false(default)} follow symlinks * - follow => {true|false(default)} follow symlinks
* - hidden => {true|false(default)} include hidden files (name starts with a '.' or is Thumbs.db) * - hidden => {true|false(default)} include hidden files (name starts with a '.' or is Thumbs.db)
* - show-deleted => {true|false(default)} get also set by hidden, if not explicitly set otherwise (requires versioning!)
* @param string|array/true $exec =null function to call with each found file/dir as first param and stat array as last param or * @param string|array/true $exec =null function to call with each found file/dir as first param and stat array as last param or
* true to return file => stat pairs * true to return file => stat pairs
* @param array $exec_params =null further params for exec as array, path is always the first param and stat the last! * @param array $exec_params =null further params for exec as array, path is always the first param and stat the last!
@ -505,6 +507,15 @@ class Vfs extends Vfs\StreamWrapper
{ {
$options['need_mime'] = true; // we need to return the mime colum $options['need_mime'] = true; // we need to return the mime colum
} }
// implicit show deleted files, if hidden is enabled (requires versioning!)
if (!empty($options['hidden']) && !isset($options['show-deleted']))
{
$options['show-deleted'] = true;
}
// make all find options available as stream context option "find", to allow plugins to use them
$context = stream_context_create(array(self::SCHEME => array('find' => $options)));
$url = $options['url']; $url = $options['url'];
if (!is_array($base)) if (!is_array($base))
@ -528,13 +539,15 @@ class Vfs extends Vfs\StreamWrapper
{ {
self::_check_add($options,$path,$result); self::_check_add($options,$path,$result);
} }
if ($is_dir && (!isset($options['maxdepth']) || ($options['maxdepth'] > 0 && $options['depth'] < $options['maxdepth'])) && ($dir = @opendir($path))) if ($is_dir && (!isset($options['maxdepth']) || ($options['maxdepth'] > 0 &&
$options['depth'] < $options['maxdepth'])) &&
($dir = @opendir($path, $context)))
{ {
while(($fname = readdir($dir)) !== false) while(($fname = readdir($dir)) !== false)
{ {
if ($fname == '.' || $fname == '..') continue; // ignore current and parent dir! if ($fname == '.' || $fname == '..') continue; // ignore current and parent dir!
if (self::is_hidden($fname) && !$options['hidden']) continue; // ignore hidden files if (self::is_hidden($fname, $options['show-deleted']) && !$options['hidden']) continue; // ignore hidden files
$file = self::concat($path, $fname); $file = self::concat($path, $fname);

View File

@ -7,7 +7,7 @@
* @package api * @package api
* @subpackage vfs * @subpackage vfs
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2008-15 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2008-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @version $Id$ * @version $Id$
*/ */
@ -313,7 +313,7 @@ class StreamWrapper implements StreamWrapperIface
*/ */
function stream_open ( $path, $mode, $options, &$opened_path ) function stream_open ( $path, $mode, $options, &$opened_path )
{ {
unset($opened_path); // not used but required by function signature unset($options,$opened_path); // not used but required by function signature
$this->opened_stream = null; $this->opened_stream = null;
$stat = null; $stat = null;
@ -325,7 +325,7 @@ class StreamWrapper implements StreamWrapperIface
{ {
return false; return false;
} }
if (!($this->opened_stream = fopen($url,$mode,$options))) if (!($this->opened_stream = fopen($url,$mode,false,$this->context)))
{ {
return false; return false;
} }
@ -869,7 +869,7 @@ class StreamWrapper implements StreamWrapperIface
if (self::LOG_LEVEL > 0) error_log(__METHOD__."( $path,$options) resolve_url_symlinks() failed!"); if (self::LOG_LEVEL > 0) error_log(__METHOD__."( $path,$options) resolve_url_symlinks() failed!");
return false; return false;
} }
if (!($this->opened_dir = opendir($this->opened_dir_url))) if (!($this->opened_dir = opendir($this->opened_dir_url, $this->context)))
{ {
if (self::LOG_LEVEL > 0) error_log(__METHOD__."( $path,$options) opendir($this->opened_dir_url) failed!"); if (self::LOG_LEVEL > 0) error_log(__METHOD__."( $path,$options) opendir($this->opened_dir_url) failed!");
return false; return false;

View File

@ -6,7 +6,7 @@
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @package filemanager * @package filemanager
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2007-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$ * @version $Id$
* *
@ -42,11 +42,8 @@ function user_pass_from_argv(&$account)
/** /**
* Give a usage message and exit * Give a usage message and exit
*
* @param string $action=null
* @param int $ret=0 exit-code
*/ */
function usage($action=null,$ret=0) function usage()
{ {
$cmd = basename(__FILE__); $cmd = basename(__FILE__);
echo "Usage:\t$cmd ls [-r|--recursive|-l|--long|-i|--inode] URL [URL2 ...]\n"; echo "Usage:\t$cmd ls [-r|--recursive|-l|--long|-i|--inode] URL [URL2 ...]\n";
@ -60,7 +57,7 @@ function usage($action=null,$ret=0)
echo "\t$cmd chmod [-r|--recursive] [ugoa]*[+-=][rwx]+,... URL [URL2 ...]\n"; echo "\t$cmd chmod [-r|--recursive] [ugoa]*[+-=][rwx]+,... URL [URL2 ...]\n";
echo "\t$cmd chown [-r|--recursive] user URL [URL2 ...]\n"; echo "\t$cmd chown [-r|--recursive] user URL [URL2 ...]\n";
echo "\t$cmd chgrp [-r|--recursive] group URL [URL2 ...]\n"; echo "\t$cmd chgrp [-r|--recursive] group URL [URL2 ...]\n";
echo "\t$cmd find URL [URL2 ...] [-type (d|f)][-depth][-mindepth n][-maxdepth n][-mime type[/sub]][-name pattern][-path pattern][-uid id][-user name][-nouser][-gid id][-group name][-nogroup][-size N][-cmin N][-ctime N][-mmin N][-mtime N] (N: +n --> >n, -n --> <n, n --> =n) [-limit N[,n]][-order (name|size|...)][-sort (ASC|DESC)]\n"; echo "\t$cmd find URL [URL2 ...] [-type (d|f)][-depth][-mindepth n][-maxdepth n][-mime type[/sub]][-name pattern][-path pattern][-uid id][-user name][-nouser][-gid id][-group name][-nogroup][-size N][-cmin N][-ctime N][-mmin N][-mtime N] (N: +n --> >n, -n --> <n, n --> =n) [-limit N[,n]][-order (name|size|...)][-sort (ASC|DESC)][-hidden][-show-deleted][-(name|name-preg|path|path-preg) S]\n";
echo "\t$cmd mount URL [path] (without path prints out the mounts)\n"; echo "\t$cmd mount URL [path] (without path prints out the mounts)\n";
echo "\t$cmd umount [-a|--all (restores default mounts)] URL|path\n"; echo "\t$cmd umount [-a|--all (restores default mounts)] URL|path\n";
echo "\t$cmd eacl URL [rwx-] [user or group]\n"; echo "\t$cmd eacl URL [rwx-] [user or group]\n";
@ -75,21 +72,21 @@ function usage($action=null,$ret=0)
exit; exit;
} }
$long = $numeric = $recursive = $perms = $all = $inode = false; $long = $numeric = $recursive = $perms = $all = $inode = false;
$argv = $_SERVER['argv']; $args = $_SERVER['argv'];
$cmd = basename(array_shift($argv),'.php'); $cmd = basename(array_shift($args),'.php');
if ($argv[0][0] != '-' && $argv[0][0] != '/' && strpos($argv[0],'://') === false) if ($args[0][0] != '-' && $args[0][0] != '/' && strpos($args[0],'://') === false)
{ {
$cmd = array_shift($argv); $cmd = array_shift($args);
} }
if (!$argv) $argv = array('-h'); if (!$args) $args = array('-h');
$args = $find_options = array(); $argv = $find_options = array();
while(!is_null($option = array_shift($argv))) while(!is_null($option = array_shift($args)))
{ {
if ($option == '-' || $option[0] != '-') // no option --> argument if ($option == '-' || $option[0] != '-') // no option --> argument
{ {
$args[] = $option; $argv[] = $option;
continue; continue;
} }
@ -100,17 +97,18 @@ while(!is_null($option = array_shift($argv)))
{ {
if (!in_array($option,array('-type','-depth','-mindepth','-maxdepth','-name','-path', if (!in_array($option,array('-type','-depth','-mindepth','-maxdepth','-name','-path',
'-uid','-user','-nouser','-gid','-group','-nogroup','-mime', '-uid','-user','-nouser','-gid','-group','-nogroup','-mime',
'-empty','-size','-cmin','-ctime','-mmin','-mtime','-limit','-order','-sort'))) '-empty','-size','-cmin','-ctime','-mmin','-mtime','-limit','-order','-sort',
'-hidden','-show-deleted','-name-preg','-path','-path-preg')))
{ {
usage(); usage();
} }
if (in_array($option,array('-empty','-depth','-nouser','-nogroup'))) if (in_array($option,array('-empty','-depth','-nouser','-nogroup','-hidden','-show-deleted')))
{ {
$find_options[substr($option,1)] = true; $find_options[substr($option,1)] = true;
} }
else else
{ {
$find_options[substr($option,1)] = array_shift($argv); $find_options[str_replace('-','_',substr($option,1))] = array_shift($args);
} }
break; break;
} }
@ -119,7 +117,7 @@ while(!is_null($option = array_shift($argv)))
{ {
for($i = 1; $i < strlen($option); ++$i) for($i = 1; $i < strlen($option); ++$i)
{ {
array_unshift($argv,'-'.$option[$i]); array_unshift($args,'-'.$option[$i]);
} }
break; break;
} }
@ -154,7 +152,7 @@ while(!is_null($option = array_shift($argv)))
break; break;
case '-d': case '--date': case '-d': case '--date':
$time = strtotime(array_shift($argv)); $time = strtotime(array_shift($args));
break; break;
case '-a': case '--all': case '-a': case '--all':
@ -162,14 +160,14 @@ while(!is_null($option = array_shift($argv)))
break; break;
case '--user': case '--user':
$user = array_shift($argv); $user = array_shift($args);
break; break;
case '--password': case '--password':
case '--passwd': case '--passwd':
$passwd = array_shift($argv); $passwd = array_shift($args);
break; break;
case '--domain': case '--domain':
$domain = array_shift($argv); $domain = array_shift($args);
break; break;
} }
} }
@ -177,7 +175,6 @@ if ($user && $passwd)
{ {
load_egw($user,$passwd,$domain ? $domain : 'default'); load_egw($user,$passwd,$domain ? $domain : 'default');
} }
$argv = $args;
$argc = count($argv); $argc = count($argv);
switch($cmd) switch($cmd)
@ -252,7 +249,7 @@ switch($cmd)
break; break;
case 'rename': case 'rename':
if (count($argv) != 2) usage(null,3); if (count($argv) != 2) usage();
load_wrapper($argv[0]); load_wrapper($argv[0]);
load_wrapper($argv[1]); load_wrapper($argv[1]);
rename($argv[0],$argv[1]); rename($argv[0],$argv[1]);
@ -422,7 +419,7 @@ switch($cmd)
echo "\n$name:\n"; echo "\n$name:\n";
} }
// separate evtl. query part, to re-add it after the file-name // separate evtl. query part, to re-add it after the file-name
$query = ''; unset($query);
list($url,$query) = explode('?',$url,2); list($url,$query) = explode('?',$url,2);
if ($query) $query = '?'.$query; if ($query) $query = '?'.$query;
@ -634,10 +631,10 @@ function do_eacl(array $argv)
* Give the stats for one file * Give the stats for one file
* *
* @param string $url * @param string $url
* @param boolean $long=false true=long listing with owner,group,size,perms, default false only filename * @param boolean $long =false true=long listing with owner,group,size,perms, default false only filename
* @param boolean $numeric=false true=give numeric uid&gid, else resolve the id to a name * @param boolean $numeric =false true=give numeric uid&gid, else resolve the id to a name
* @param boolean $full_path=false true=give full path instead of just filename * @param boolean $full_path =false true=give full path instead of just filename
* @param boolean $inode=false true=display inode (sqlfs id) * @param boolean $inode =false true=display inode (sqlfs id)
*/ */
function do_stat($url,$long=false,$numeric=false,$full_path=false,$inode=false) function do_stat($url,$long=false,$numeric=false,$full_path=false,$inode=false)
{ {
@ -724,8 +721,9 @@ function do_cp($argv,$recursive=false,$perms=false)
if (count($argv) > 1 && $to_exists && !is_dir($to)) if (count($argv) > 1 && $to_exists && !is_dir($to))
{ {
usage(null,4); usage();
} }
$anz_dirs = $anz_files = 0;
foreach($argv as $from) foreach($argv as $from)
{ {
if (is_dir($from) && (!file_exists($to) || is_dir($to)) && $recursive && class_exists('egw_vfs')) if (is_dir($from) && (!file_exists($to) || is_dir($to)) && $recursive && class_exists('egw_vfs'))
@ -755,11 +753,11 @@ function do_cp($argv,$recursive=false,$perms=false)
} }
} }
function _cp($from,$to,$verbose=false,$perms=false) function _cp($from,$to,$verbose=false)
{ {
load_wrapper($from); load_wrapper($from);
if (is_dir($to) || !file_exists($to) && is_dir($from) && $mkdir) if (is_dir($to))
{ {
$path = egw_vfs::parse_url($from,PHP_URL_PATH); $path = egw_vfs::parse_url($from,PHP_URL_PATH);
if (is_dir($to)) if (is_dir($to))
@ -831,7 +829,7 @@ function do_lntree($from,$to)
if (!file_exists($from) || $to[0] != '/' || file_exists($to) || !is_writable(dirname($to))) if (!file_exists($from) || $to[0] != '/' || file_exists($to) || !is_writable(dirname($to)))
{ {
usage(null,4); usage();
} }
egw_vfs::find($from, array( egw_vfs::find($from, array(
'url' => true, 'url' => true,

View File

@ -5,12 +5,13 @@
* @link http://www.egroupware.org/ * @link http://www.egroupware.org/
* @package filemanager * @package filemanager
* @author Ralf Becker <rb-AT-stylite.de> * @author Ralf Becker <rb-AT-stylite.de>
* @copyright (c) 2010-15 by Ralf Becker <rb-AT-stylite.de> * @copyright (c) 2010-16 by Ralf Becker <rb-AT-stylite.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$ * @version $Id$
*/ */
use EGroupware\Stylite\Vfs\Versioning; use EGroupware\Stylite\Vfs\Versioning;
use EGroupware\Api\Vfs;
/** /**
* Filemanager: mounting GUI * Filemanager: mounting GUI
@ -83,24 +84,24 @@ class filemanager_admin extends filemanager_ui
{ {
$msg = $this->sudo($content['user'],$content['password'],self::$is_setup) ? $msg = $this->sudo($content['user'],$content['password'],self::$is_setup) ?
lang('Root access granted.') : lang('Wrong username or password!'); lang('Root access granted.') : lang('Wrong username or password!');
$msg_type = egw_vfs::$is_root ? 'success' : 'error'; $msg_type = Vfs::$is_root ? 'success' : 'error';
} }
elseif ($content['etemplates'] && $GLOBALS['egw_info']['user']['apps']['admin']) elseif ($content['etemplates'] && $GLOBALS['egw_info']['user']['apps']['admin'])
{ {
$path = '/etemplates'; $path = '/etemplates';
$url = 'stylite.merge://default/etemplates?merge=.&lang=0&level=1&extension=xet&url=egw'; $url = 'stylite.merge://default/etemplates?merge=.&lang=0&level=1&extension=xet&url=egw';
$backup = egw_vfs::$is_root; $backup = Vfs::$is_root;
egw_vfs::$is_root = true; Vfs::$is_root = true;
$msg = egw_vfs::mount($url, $path) ? $msg = Vfs::mount($url, $path) ?
lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path); lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path);
egw_vfs::$is_root = $backup; Vfs::$is_root = $backup;
} }
elseif (egw_vfs::$is_root) elseif (Vfs::$is_root)
{ {
if ($content['logout']) if ($content['logout'])
{ {
$msg = $this->sudo('','',self::$is_setup) ? 'Logout failed!' : lang('Root access stopped.'); $msg = $this->sudo('','',self::$is_setup) ? 'Logout failed!' : lang('Root access stopped.');
$msg_type = !egw_vfs::$is_root ? 'success' : 'error'; $msg_type = !Vfs::$is_root ? 'success' : 'error';
} }
if ($content['mounts']['disable'] || self::$is_setup && $content['mounts']['umount']) if ($content['mounts']['disable'] || self::$is_setup && $content['mounts']['umount'])
{ {
@ -114,12 +115,12 @@ class filemanager_admin extends filemanager_ui
} }
if (!in_array($path, self::$protected_path) && $path != '/') if (!in_array($path, self::$protected_path) && $path != '/')
{ {
$msg = egw_vfs::umount($path) ? $msg = Vfs::umount($path) ?
lang('%1 successful unmounted.',$path) : lang('Error unmounting %1!',$path); lang('%1 successful unmounted.',$path) : lang('Error unmounting %1!',$path);
} }
else // re-mount / with sqlFS, to disable versioning else // re-mount / with sqlFS, to disable versioning
{ {
$msg = egw_vfs::mount($url=sqlfs_stream_wrapper::SCHEME.'://default'.$path,$path) ? $msg = Vfs::mount($url=sqlfs_stream_wrapper::SCHEME.'://default'.$path,$path) ?
lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path); lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path);
} }
} }
@ -134,7 +135,7 @@ class filemanager_admin extends filemanager_ui
$msg = lang('Versioning requires <a href="http://www.egroupware.org/products">Stylite EGroupware Enterprise Line (EPL)</a>!'); $msg = lang('Versioning requires <a href="http://www.egroupware.org/products">Stylite EGroupware Enterprise Line (EPL)</a>!');
$msg_type = 'info'; $msg_type = 'info';
} }
elseif (!egw_vfs::file_exists($path) || !egw_vfs::is_dir($path)) elseif (!Vfs::file_exists($path) || !Vfs::is_dir($path))
{ {
$msg = lang('Path %1 not found or not a directory!',$path); $msg = lang('Path %1 not found or not a directory!',$path);
$msg_type = 'error'; $msg_type = 'error';
@ -147,7 +148,7 @@ class filemanager_admin extends filemanager_ui
} }
else else
{ {
$msg = egw_vfs::mount($url,$path) ? $msg = Vfs::mount($url,$path) ?
lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path); lang('Successful mounted %1 on %2.',$url,$path) : lang('Error mounting %1 on %2!',$url,$path);
} }
} }
@ -158,16 +159,56 @@ class filemanager_admin extends filemanager_ui
$msg = lang('Configuration changed.'); $msg = lang('Configuration changed.');
} }
} }
// delete old versions and deleted files
if ($content['delete-versions'])
{
if (!Versioning\StreamWrapper::check_delete_version(null))
{
$msg = lang('Permission denied')."\n\n".lang('You are NOT allowed to finally delete older versions and deleted files!');
}
// we need to be root to delete files independent of permissions and ownership
Vfs::$is_root = true;
if (!Vfs::file_exists($content['versionedpath']) || !Vfs::is_dir($content['versionedpath']))
{
$msg = lang('Directory "%1" NOT found!', $content['versionedpath']);
}
else
{
$deleted = $errors = 0;
Vfs::find($content['versionedpath'], array(
'show-deleted' => true,
'hidden' => true,
'path_preg' => '#/\.versions/#',
)+(!(int)$content['ctime'] ? array() : array(
'ctime' => ($content['ctime']<0?'-':'+').(int)$content['ctime'],
)), function($path) use (&$deleted, &$errors)
{
if (Vfs::unlink($path))
{
++$deleted;
}
else
{
++$errors;
}
});
$msg = $errors ? lang('%1 files deleted with %2 errors!', $deleted, $errors) : lang('%1 files deleted.', $deleted);
}
Vfs::$is_root = false;
}
} }
if (true) $content = array(); if (true) $content = array(
'versionedpath' => $content['versionedpath'],
'ctime' => $content['ctime'],
);
if ($this->versioning) if ($this->versioning)
{ {
// statistical information // statistical information
$content = Versioning\StreamWrapper::summary(); $content += Versioning\StreamWrapper::summary();
if ($content['total_files']) $content['percent_files'] = number_format(100.0*$content['version_files']/$content['total_files'],1).'%'; if ($content['total_files']) $content['percent_files'] = number_format(100.0*$content['version_files']/$content['total_files'],1).'%';
if ($content['total_size']) $content['percent_size'] = number_format(100.0*$content['version_size']/$content['total_size'],1).'%'; if ($content['total_size']) $content['percent_size'] = number_format(100.0*$content['version_size']/$content['total_size'],1).'%';
} }
if (!($content['is_root']=egw_vfs::$is_root)) if (!($content['is_root']=Vfs::$is_root))
{ {
if (empty($msg)) if (empty($msg))
{ {
@ -183,14 +224,14 @@ class filemanager_admin extends filemanager_ui
$n = 2; $n = 2;
$content['mounts'] = array(); $content['mounts'] = array();
foreach(egw_vfs::mount() as $path => $url) foreach(Vfs::mount() as $path => $url)
{ {
$content['mounts'][$n++] = array( $content['mounts'][$n++] = array(
'path' => $path, 'path' => $path,
'url' => $url, 'url' => $url,
); );
$readonlys["disable[$path]"] = !$this->versioning || !egw_vfs::$is_root || $readonlys["disable[$path]"] = !$this->versioning || !Vfs::$is_root ||
egw_vfs::parse_url($url,PHP_URL_SCHEME) != $this->versioning; Vfs::parse_url($url,PHP_URL_SCHEME) != $this->versioning;
} }
$readonlys['umount[/]'] = $readonlys['umount[/apps]'] = true; // do not allow to unmount / or /apps $readonlys['umount[/]'] = $readonlys['umount[/apps]'] = true; // do not allow to unmount / or /apps
$readonlys['url'] = !self::$is_setup; $readonlys['url'] = !self::$is_setup;
@ -203,7 +244,7 @@ class filemanager_admin extends filemanager_ui
); );
// show [Mount /etemplates] button for admin, if not already mounted and available // show [Mount /etemplates] button for admin, if not already mounted and available
$readonlys['etemplates'] = !class_exists('\EGroupware\Stylite\Vfs\Merge\StreamWrapper') || $readonlys['etemplates'] = !class_exists('\EGroupware\Stylite\Vfs\Merge\StreamWrapper') ||
($fs_tab=egw_vfs::mount($url)) && isset($fs_tab['/etemplates']) || ($fs_tab=Vfs::mount($url)) && isset($fs_tab['/etemplates']) ||
!isset($GLOBALS['egw_info']['user']['apps']['admin']); !isset($GLOBALS['egw_info']['user']['apps']['admin']);
//_debug_array($content); //_debug_array($content);

View File

@ -5,7 +5,7 @@
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @package filemanager * @package filemanager
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2008-14 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @copyright (c) 2008-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$ * @version $Id$
*/ */
@ -737,7 +737,8 @@ class filemanager_ui
// now we use find to loop through all files and dirs: (selected only contains dirs now) // now we use find to loop through all files and dirs: (selected only contains dirs now)
// - depth=true to get first the files and then the dir containing it // - depth=true to get first the files and then the dir containing it
// - hidden=true to also return hidden files (eg. Thumbs.db), as we cant delete non-empty dirs // - hidden=true to also return hidden files (eg. Thumbs.db), as we cant delete non-empty dirs
foreach(egw_vfs::find($selected,array('depth'=>true,'hidden'=>true)) as $path) // - show-deleted=false to not (finally) deleted versioned files
foreach(egw_vfs::find($selected,array('depth'=>true,'hidden'=>true,'show-deleted'=>false)) as $path)
{ {
if (($is_dir = egw_vfs::is_dir($path) && !egw_vfs::is_link($path)) && egw_vfs::rmdir($path,0)) if (($is_dir = egw_vfs::is_dir($path) && !egw_vfs::is_link($path)) && egw_vfs::rmdir($path,0))
{ {

View File

@ -10,6 +10,7 @@
%1 failed, %2 succeded filemanager de %1 fehlgeschlagen, %2 erfolgreich %1 failed, %2 succeded filemanager de %1 fehlgeschlagen, %2 erfolgreich
%1 files common de %1 Dateien %1 files common de %1 Dateien
%1 files copied. filemanager de %1 Dateien kopiert. %1 files copied. filemanager de %1 Dateien kopiert.
%1 files deleted with %2 errors! filemanager de %1 Dateien gelöscht mit %2 Fehlern!
%1 files deleted. filemanager de %1 Dateien gelöscht. %1 files deleted. filemanager de %1 Dateien gelöscht.
%1 files moved. filemanager de %1 Dateien verschoben. %1 files moved. filemanager de %1 Dateien verschoben.
%1 shares deleted. filemanager de %1 Freigaben gelöscht. %1 shares deleted. filemanager de %1 Freigaben gelöscht.
@ -24,6 +25,7 @@
%d erros while moving, %d files successfully moved. filemanager de %d Fehler beim Verschieben (%d Dateien erfolgreich verschoben)! %d erros while moving, %d files successfully moved. filemanager de %d Fehler beim Verschieben (%d Dateien erfolgreich verschoben)!
%d files successfully copied. filemanager de %d Dateien erfolgreich kopiert %d files successfully copied. filemanager de %d Dateien erfolgreich kopiert
%d files successfully moved. filemanager de %d Dateien erfolgreich verschoben %d files successfully moved. filemanager de %d Dateien erfolgreich verschoben
0 means all, -n newer then n days filemanager de 0 für alle, -N für neuer als N Tage
accessrights filemanager de Zugangsberechtigungen accessrights filemanager de Zugangsberechtigungen
acl added. filemanager de Zugriffsrecht hinzugefügt. acl added. filemanager de Zugriffsrecht hinzugefügt.
acl deleted. filemanager de Zugriffsrecht gelöscht. acl deleted. filemanager de Zugriffsrecht gelöscht.
@ -50,6 +52,7 @@ clear search filemanager de Suchfelder zurücksetzen
clipboard is empty! filemanager de Zwischenablage ist leer! clipboard is empty! filemanager de Zwischenablage ist leer!
comment filemanager de Kommentar comment filemanager de Kommentar
configuration changed. filemanager de Konfiguration geändert. configuration changed. filemanager de Konfiguration geändert.
confirm final delete filemanager de Endgültiges Löschen bestätigen
copied filemanager de kopiert copied filemanager de kopiert
copied %1 to %2 filemanager de %1 nach %2 kopiert copied %1 to %2 filemanager de %1 nach %2 kopiert
copy filemanager de Kopieren copy filemanager de Kopieren
@ -74,12 +77,14 @@ cut filemanager de Ausschneiden
cut to clipboard filemanager de Ausschneiden in die Zwischenablage cut to clipboard filemanager de Ausschneiden in die Zwischenablage
default behavior is no. the link will not be shown, but you are still able to navigate to this location, or configure this paricular location as startfolder or folderlink. filemanager de Vorgabe ist NEIN. Der Verweis wird nicht angezeigt, Sie können aber immer zu diesem Verzeichnis navigieren, Sie können aber das Verzeichnis als Startverzeichnis oder als Verzeichnisverweis konfigurieren. default behavior is no. the link will not be shown, but you are still able to navigate to this location, or configure this paricular location as startfolder or folderlink. filemanager de Vorgabe ist NEIN. Der Verweis wird nicht angezeigt, Sie können aber immer zu diesem Verzeichnis navigieren, Sie können aber das Verzeichnis als Startverzeichnis oder als Verzeichnisverweis konfigurieren.
default document to insert entries filemanager de Standarddokument zum Einfügen von Daten default document to insert entries filemanager de Standarddokument zum Einfügen von Daten
delete all older versions and deleted files older then %s days filemanager de Lösche alle alten Versionen und gelösche Dateien älter als %s Tage
delete these files or directories? filemanager de Diese Dateien oder Verzeichnisse löschen? delete these files or directories? filemanager de Diese Dateien oder Verzeichnisse löschen?
delete these shares? filemanager de Diese Freigaben löschen? delete these shares? filemanager de Diese Freigaben löschen?
delete this file or directory filemanager de Datei oder Verzeichnis löschen delete this file or directory filemanager de Datei oder Verzeichnis löschen
deleted %1 filemanager de %1 gelöscht deleted %1 filemanager de %1 gelöscht
directories sorted in filemanager de Verzeichnisse einsortiert directories sorted in filemanager de Verzeichnisse einsortiert
directory filemanager de Verzeichnis directory filemanager de Verzeichnis
directory "%1" not found! filemanager de Verzeichnis "%1" NICHT gefunden!
directory %1 already exists filemanager de Verzeichnis %1 existiert bereits directory %1 already exists filemanager de Verzeichnis %1 existiert bereits
directory %1 does not exist filemanager de Verzeichnis %1 existiert nicht directory %1 does not exist filemanager de Verzeichnis %1 existiert nicht
directory not found or no permission to access it! filemanager de Verzeichnis wurde nicht gefunden oder Sie haben keine Rechte um darauf zuzugreifen! directory not found or no permission to access it! filemanager de Verzeichnis wurde nicht gefunden oder Sie haben keine Rechte um darauf zuzugreifen!
@ -137,6 +142,8 @@ files from links filemanager de Zeige Dateien aus verknüpften Einträgen
files from subdirectories filemanager de Dateien aus Unterverzeichnissen files from subdirectories filemanager de Dateien aus Unterverzeichnissen
files in this directory filemanager de Dateien in diesem Verzeichnis files in this directory filemanager de Dateien in diesem Verzeichnis
filesystem check reported no problems. filemanager de Überprüfung des Dateisystem ergab keine Probleme. filesystem check reported no problems. filemanager de Überprüfung des Dateisystem ergab keine Probleme.
finally delete filemanager de Endgültig löschen
finally delete all older versions and deleted files under given directory.\n\nthis can not be undone! filemanager de Ältere Versionen und gelöschte Dateien unter dem angegebenen Verzeichnis endgültig löschen.\n\nDas kann NICHT rückgängig gemacht werden!
finally delete this version filemanager de Diese Version endgültig löschen finally delete this version filemanager de Diese Version endgültig löschen
fix reported problems filemanager de Gefundene Probleme beheben fix reported problems filemanager de Gefundene Probleme beheben
folder up filemanager de Übergeordnetes Verzeichnis folder up filemanager de Übergeordnetes Verzeichnis
@ -171,6 +178,7 @@ modified filemanager de verändert
modified between filemanager de verändert zwischen modified between filemanager de verändert zwischen
modify all subdirectories and their content filemanager de Änderungen auf alle Unterverzeichnisse und ihre Inhalte anwenden modify all subdirectories and their content filemanager de Änderungen auf alle Unterverzeichnisse und ihre Inhalte anwenden
mount filemanager de Mount mount filemanager de Mount
mount /etemplates to allow customizing of etemplates filemanager de /etemplates mounten um eTemplate anpassen zu können
mountpoints filemanager de Mountpoints mountpoints filemanager de Mountpoints
move filemanager de verschieben move filemanager de verschieben
move into folder filemanager de Verschieben in Ordner move into folder filemanager de Verschieben in Ordner
@ -264,10 +272,12 @@ upload files filemanager de Dateien hochladen
use this tag for addresslabels. put the content, you want to repeat, between two tags. filemanager de Benutzen Sie dieses Symbol für Adressetiketten. Stellen Sie den Inhalt der wiederholt werden soll zwischen 2 Symbole. use this tag for addresslabels. put the content, you want to repeat, between two tags. filemanager de Benutzen Sie dieses Symbol für Adressetiketten. Stellen Sie den Inhalt der wiederholt werden soll zwischen 2 Symbole.
used space filemanager de Benutzter Platz used space filemanager de Benutzter Platz
users and groups filemanager de Benutzer und Gruppen users and groups filemanager de Benutzer und Gruppen
versioned directory filemanager de Versioniertes Verzeichnis
versioning filemanager de Versionierung versioning filemanager de Versionierung
vfs mounts and versioning common de VFS einhängen und versionieren vfs mounts and versioning common de VFS einhängen und versionieren
who should be allowed to finally delete deleted files or old versions of a file: filemanager de Wer soll gelöschte Dateien oder ältere Versionen endgültig löschen dürfen: who should be allowed to finally delete deleted files or old versions of a file: filemanager de Wer soll gelöschte Dateien oder ältere Versionen endgültig löschen dürfen:
wrong username or password! filemanager de Falscher Benutzername oder Passwort! wrong username or password! filemanager de Falscher Benutzername oder Passwort!
you are not allowed to finally delete older versions and deleted files! filemanager de Sie haben nicht die Berechtigung ältere Versionen oder gelöschte Dateien endgültig zu löschen!
you are not allowed to upload a script! filemanager de Sie dürfen KEINE Skripte hochladen! you are not allowed to upload a script! filemanager de Sie dürfen KEINE Skripte hochladen!
you can only grant additional rights, you can not take rights away! filemanager de Sie können nur zusätzliche Rechte gewähren, Rechte können NICHT weg genommen werden! you can only grant additional rights, you can not take rights away! filemanager de Sie können nur zusätzliche Rechte gewähren, Rechte können NICHT weg genommen werden!
you do not have access to %1 filemanager de Sie besitzen keine Zugriffsrechte für %1 you do not have access to %1 filemanager de Sie besitzen keine Zugriffsrechte für %1

View File

@ -10,6 +10,7 @@
%1 failed, %2 succeded filemanager en %1 failed, %2 succeeded. %1 failed, %2 succeded filemanager en %1 failed, %2 succeeded.
%1 files common en %1 files %1 files common en %1 files
%1 files copied. filemanager en %1 files copied. %1 files copied. filemanager en %1 files copied.
%1 files deleted with %2 errors! filemanager en %1 files deleted with %2 errors!
%1 files deleted. filemanager en %1 files deleted. %1 files deleted. filemanager en %1 files deleted.
%1 files moved. filemanager en %1 files moved. %1 files moved. filemanager en %1 files moved.
%1 shares deleted. filemanager en %1 shares deleted. %1 shares deleted. filemanager en %1 shares deleted.
@ -24,6 +25,7 @@
%d erros while moving, %d files successfully moved. filemanager en %d errors while moving, %d files successfully moved. %d erros while moving, %d files successfully moved. filemanager en %d errors while moving, %d files successfully moved.
%d files successfully copied. filemanager en %d files successfully copied. %d files successfully copied. filemanager en %d files successfully copied.
%d files successfully moved. filemanager en %d files successfully moved. %d files successfully moved. filemanager en %d files successfully moved.
0 means all, -n newer then n days filemanager en 0 means all, -N newer then N days
accessrights filemanager en Access rights accessrights filemanager en Access rights
acl added. filemanager en ACL added. acl added. filemanager en ACL added.
acl deleted. filemanager en ACL deleted. acl deleted. filemanager en ACL deleted.
@ -50,6 +52,7 @@ clear search filemanager en Clear search
clipboard is empty! filemanager en Clipboard is empty! clipboard is empty! filemanager en Clipboard is empty!
comment filemanager en Comment comment filemanager en Comment
configuration changed. filemanager en Configuration changed. configuration changed. filemanager en Configuration changed.
confirm final delete filemanager en Confirm final delete
copied filemanager en Copied copied filemanager en Copied
copied %1 to %2 filemanager en Copied %1 to %2 copied %1 to %2 filemanager en Copied %1 to %2
copy filemanager en Copy copy filemanager en Copy
@ -74,12 +77,14 @@ cut filemanager en Cut
cut to clipboard filemanager en Cut to clipboard cut to clipboard filemanager en Cut to clipboard
default behavior is no. the link will not be shown, but you are still able to navigate to this location, or configure this paricular location as startfolder or folderlink. filemanager en Default = No. The link will not be shown, but you are still able to navigate to this location, or configure this particular location as start folder or folder link. default behavior is no. the link will not be shown, but you are still able to navigate to this location, or configure this paricular location as startfolder or folderlink. filemanager en Default = No. The link will not be shown, but you are still able to navigate to this location, or configure this particular location as start folder or folder link.
default document to insert entries filemanager en Default document to insert entries default document to insert entries filemanager en Default document to insert entries
delete all older versions and deleted files older then %s days filemanager en Delete all older versions and deleted files older then %s days
delete these files or directories? filemanager en Delete these files or directories? delete these files or directories? filemanager en Delete these files or directories?
delete these shares? filemanager en Delete these shares? delete these shares? filemanager en Delete these shares?
delete this file or directory filemanager en Delete this file or directory delete this file or directory filemanager en Delete this file or directory
deleted %1 filemanager en Deleted %1 deleted %1 filemanager en Deleted %1
directories sorted in filemanager en Directories sorted in directories sorted in filemanager en Directories sorted in
directory filemanager en Directory directory filemanager en Directory
directory "%1" not found! filemanager en Directory "%1" NOT found!
directory %1 already exists filemanager en Directory %1 already exists. directory %1 already exists filemanager en Directory %1 already exists.
directory %1 does not exist filemanager en Directory %1 does not exist. directory %1 does not exist filemanager en Directory %1 does not exist.
directory not found or no permission to access it! filemanager en Directory not found or no permission to access it! directory not found or no permission to access it! filemanager en Directory not found or no permission to access it!
@ -137,6 +142,8 @@ files from links filemanager en Files from links
files from subdirectories filemanager en Files from sub directories files from subdirectories filemanager en Files from sub directories
files in this directory filemanager en Files in this directory files in this directory filemanager en Files in this directory
filesystem check reported no problems. filemanager en Filesystem check reported no problems. filesystem check reported no problems. filemanager en Filesystem check reported no problems.
finally delete filemanager en Finally delete
finally delete all older versions and deleted files under given directory.\n\nthis can not be undone! filemanager en Finally delete all older versions and deleted files under given directory.\n\nThis can NOT be undone!
finally delete this version filemanager en Finally delete this version finally delete this version filemanager en Finally delete this version
fix reported problems filemanager en Fix reported problems fix reported problems filemanager en Fix reported problems
folder up filemanager en Folder up folder up filemanager en Folder up
@ -171,6 +178,7 @@ modified filemanager en Modified
modified between filemanager en Modified between modified between filemanager en Modified between
modify all subdirectories and their content filemanager en Modify all sub directories and their content modify all subdirectories and their content filemanager en Modify all sub directories and their content
mount filemanager en Mount mount filemanager en Mount
mount /etemplates to allow customizing of etemplates filemanager en Mount /etemplates to allow customizing of eTemplates
mountpoints filemanager en Mountpoints mountpoints filemanager en Mountpoints
move filemanager en Move move filemanager en Move
move into folder filemanager en Move into folder move into folder filemanager en Move into folder
@ -264,10 +272,12 @@ upload files filemanager en Upload files
use this tag for addresslabels. put the content, you want to repeat, between two tags. filemanager en Use this tag for addresslabels. Put the content, you want to repeat, between two tags. use this tag for addresslabels. put the content, you want to repeat, between two tags. filemanager en Use this tag for addresslabels. Put the content, you want to repeat, between two tags.
used space filemanager en Used space used space filemanager en Used space
users and groups filemanager en Users and groups users and groups filemanager en Users and groups
versioned directory filemanager en Versioned directory
versioning filemanager en Versioning versioning filemanager en Versioning
vfs mounts and versioning common en VFS mounts and versioning vfs mounts and versioning common en VFS mounts and versioning
who should be allowed to finally delete deleted files or old versions of a file: filemanager en Who should be allowed to finally delete deleted files or old versions of a file: who should be allowed to finally delete deleted files or old versions of a file: filemanager en Who should be allowed to finally delete deleted files or old versions of a file:
wrong username or password! filemanager en Wrong username or password! wrong username or password! filemanager en Wrong username or password!
you are not allowed to finally delete older versions and deleted files! filemanager en You are NOT allowed to finally delete older versions and deleted files!
you are not allowed to upload a script! filemanager en You are NOT allowed to upload a script! you are not allowed to upload a script! filemanager en You are NOT allowed to upload a script!
you can only grant additional rights, you can not take rights away! filemanager en You can only grant additional rights, you can NOT take rights away! you can only grant additional rights, you can not take rights away! filemanager en You can only grant additional rights, you can NOT take rights away!
you do not have access to %1 filemanager en You do not have access to %1 you do not have access to %1 filemanager en You do not have access to %1

View File

@ -68,6 +68,11 @@
<menulist> <menulist>
<menupopup id="allow_delete_versions" onchange="1" label="Who should be allowed to finally delete deleted files or old versions of a file:" disabled="!@versioning"/> <menupopup id="allow_delete_versions" onchange="1" label="Who should be allowed to finally delete deleted files or old versions of a file:" disabled="!@versioning"/>
</menulist> </menulist>
<hbox disabled="!@versioning">
<integer id="ctime" label="Delete all older versions and deleted files older then %s days" statustext="0 means all, -N newer then N days"/>
<textbox size="30" id="versionedpath" blur="Versioned directory"/>
<button id="delete-versions" label="Finally delete" onclick="et2_dialog.confirm(widget,'Finally delete all older versions and deleted files under given directory.\n\nThis can NOT be undone!','Confirm final delete');" image="delete" background_image="1"/>
</hbox>
<grid> <grid>
<columns> <columns>
<column/> <column/>