Implemented symlinks for eGW's VFS:

- sqlfs can store now symlinks (implements symlink and readlink)
- vfs resolves symlinks before calling a mounted stream-wrapper
--> symlinks can be between different mount-points
- filemanger can create symlinks and follows them
- etemplate vfs_widget displays symlinks (to be improved)
Happy testing :-)
This commit is contained in:
Ralf Becker 2009-03-19 20:12:35 +00:00
parent 52db44fb83
commit 55d2aaa3ee
10 changed files with 435 additions and 101 deletions

View File

@ -133,6 +133,24 @@ class vfs_widget
}
$value['c'.$n] = $component;
$path .= '/'.$component;
// replace id's in /apps again with human readable titles
$path_parts = explode('/',$path);
if ($path_parts[1] == 'apps')
{
switch(count($path_parts))
{
case 2:
$value['c'.$n] = lang('Applications');
break;
case 3:
$value['c'.$n] = lang($path_parts[2]);
break;
case 4:
$value['c'.$n] .= ': '.egw_link::title($path_parts[2],$path_parts[3]);
//$value['c'.$n] = egw_link::title($path_parts[2],$path_parts[3]);
break;
}
}
if (egw_vfs::check_access($path,egw_vfs::READABLE)) // show link only if we have access to the file or dir
{
if ($n < count($comps)-1 || $mime == egw_vfs::DIR_MIME_TYPE)
@ -201,6 +219,16 @@ class vfs_widget
{
$value = egw_vfs::mime_icon($mime);
}
// mark symlinks (check if method exists, to allow etemplate to run on 1.6 API!)
if (method_exists('egw_vfs','is_link') && egw_vfs::is_link($path))
{
$broken = !egw_vfs::stat($path);
list($span,$class) = explode(',',$cell['span'],2);
$class .= ($class ? ' ' : '') . ($broken ? 'vfsIsBrokenLink' : 'vfsIsLink');
$cell['span'] = $span.','.$class;
$cell['label'] = ($broken ? lang('Broken link') : lang('Link')).': '.egw_vfs::readlink($path).
(!$broken ? ' ('.$cell['label'].')' : '');
}
break;
default:

View File

@ -11,12 +11,12 @@
/*
* a few generic styles used in most eT apps
*/
.redItalic,.message {
color: red;
font-style: italic;
.redItalic,.message {
color: red;
font-style: italic;
}
.gray {
color: gray;
.gray {
color: gray;
}
.leftPad5 {
padding-left: 5px;
@ -31,24 +31,24 @@
}
/*
* Styles of the eT editor
* Styles of the eT editor
*/
.clickWidgetToEdit {
cursor: pointer;
display: inline;
.clickWidgetToEdit {
cursor: pointer;
display: inline;
}
.clickWidgetToEdit:hover {
background-color: pink;
.clickWidgetToEdit:hover {
background-color: pink;
}
/*
* Styles of the nextmatch widget
* Styles of the nextmatch widget
*/
.activ_sortcolumn {
font-weight: bold;
.activ_sortcolumn {
font-weight: bold;
}
.inactiv_sortcolumn {
font-weight: normal;
.inactiv_sortcolumn {
font-weight: normal;
}
.lettersearch,.lettersearch_active {
background-color: #D3DCE3;
@ -80,30 +80,30 @@
/*
* Styles for the tab widget
*/
.etemplate_tab,.etemplate_tab_active {
border-style:solid;
border-width:1px 1px 0px;
border-color:black;
padding:3px;
padding-left: 6px;
padding-right: 6px;
width: 60px;
.etemplate_tab,.etemplate_tab_active {
border-style:solid;
border-width:1px 1px 0px;
border-color:black;
padding:3px;
padding-left: 6px;
padding-right: 6px;
width: 60px;
white-space: nowrap;
}
.etemplate_tab {
cursor: pointer;
.etemplate_tab {
cursor: pointer;
background-color: #E8F0F0;
}
.etemplate_tab_active {
border-width:2px 2px 0px;
.etemplate_tab_active {
border-width:2px 2px 0px;
background-color: #D3DCE3;
}
.tab_body {
border: black solid 2px;
.tab_body {
border: black solid 2px;
}
.nextmatch_header {
border: 1px solid black;
.nextmatch_header {
border: 1px solid black;
}
.nextmatch_header select {
width: 140px;
@ -120,4 +120,24 @@
}
.vfsFilename {
white-space: nowrap;
}
}
/**
* mark a file (icon) as link
*/
.vfsIsLink img {
border-bottom: 4px solid darkgray;
border-right: 4px solid darkgray;
}
/**
* nicer would be, but it's not working ...
*/
.vfsIsLink img:after {
content: url(filemanager/templates/default/images/link.png);
}
/**
* mark a link (icon) as broken link
*/
.vfsIsBrokenLink img {
border-bottom: 4px solid red;
border-right: 4px solid red;
}

View File

@ -170,6 +170,20 @@ class filemanager_ui
$content['nm']['path'] = $old_path;
}
break;
case 'symlink':
$target = $content['nm']['path'];
$ses = $GLOBALS['egw']->session->appsession('index','filemanager');
$content['nm']['path'] = $ses['path'];
$link = egw_vfs::concat($content['nm']['path'],basename($target));
$abs_target = $target[0] == '/' ? $target : egw_vfs::concat($content['nm']['path'],$target);
if (!egw_vfs::stat($abs_target))
{
$content['nm']['msg'] = lang('Link target %1 not found!',$abs_target);
break;
}
$content['nm']['msg'] = egw_vfs::symlink($target,$link) ?
lang('Symlink to %1 created.',$target) : lang('Error creating symlink to target %1!',$target);
break;
case 'paste':
$content['nm']['msg'] = self::action($clipboard_type.'_paste',$clipboard_files,$content['nm']['path']);
break;
@ -223,6 +237,7 @@ class filemanager_ui
$readonlys['button[paste]'] = !$clipboard_files;
$readonlys['button[createdir]'] = !$dir_is_writable;
$readonlys['button[symlink]'] = !$dir_is_writable;
$readonlys['button[upload]'] = $readonlys['upload'] = !$dir_is_writable;
if ($dir_is_writable || !$content['nm']['filter']) $sel_options['action']['delete'] = lang('Delete');
@ -357,7 +372,7 @@ class filemanager_ui
$dirs = $files = $errs = 0;
foreach(egw_vfs::find($selected,array('depth'=>true)) as $path)
{
if (($is_dir = egw_vfs::is_dir($path)) && egw_vfs::rmdir($path,0))
if (($is_dir = egw_vfs::is_dir($path) && !egw_vfs::is_link($path)) && egw_vfs::rmdir($path,0))
{
++$dirs;
}
@ -503,10 +518,9 @@ class filemanager_ui
'limit' => (int)$query['num_rows'].','.(int)$query['start'],
'need_mime' => true,
'name_preg' => $namefilter,
'follow' => true, // follow symlinks
),true) as $path => $row)
{
$row['icon'] = egw_vfs::mime_icon($row['mime']);
//echo $path; _debug_array($row);
$rows[++$n] = $row;
$path2n[$path] = $n;
@ -552,13 +566,11 @@ class filemanager_ui
*/
function file(array $content=null,$msg='')
{
static $tabs = 'general|perms|eacl|preview|custom';
$tpl = new etemplate('filemanager.file');
if (!is_array($content))
{
if (!($stat = egw_vfs::stat($path = $_GET['path'])))
if (!($path = $_GET['path']) || !($stat = egw_vfs::lstat($path)))
{
$content['msg'] = lang('File or directory not found!');
}
@ -576,9 +588,13 @@ class filemanager_ui
{
foreach($props as $prop) $content[$prop['name']] = $prop['val'];
}
if (($content['is_link'] = egw_vfs::is_link($path)))
{
$content['symlink'] = egw_vfs::readlink($path);
}
}
$content[$tabs] = $_GET['tabs'];
if (!($content['is_dir'] = egw_vfs::is_dir($path)))
$content['tabs'] = $_GET['tabs'];
if (!($content['is_dir'] = egw_vfs::is_dir($path) && !egw_vfs::is_link($path)))
{
$content['perms']['executable'] = (int)!!($content['mode'] & 0111);
$mask = 6;
@ -742,6 +758,10 @@ class filemanager_ui
echo "<html>\n<body>\n<script>\n$js\n</script>\n</body>\n</html>\n";
if ($button == 'save')$GLOBALS['egw']->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['msg'] = $msg;
@ -758,13 +778,14 @@ class filemanager_ui
}
$readonlys['name'] = $path == '/' || !egw_vfs::is_writable($content['dir']);
$readonlys['comment'] = !egw_vfs::is_writable($path);
$readonlys['tabs']['preview'] = $readonlys['tabs']['perms'] = $content['is_link'];
// if neither owner nor is writable --> disable save&apply
$readonlys['button[save]'] = $readonlys['button[apply]'] = !$content['is_owner'] && !egw_vfs::is_writable($path);
if (!($cfs = config::get_customfields('filemanager')))
{
$readonlys[$tabs]['custom'] = true;
$readonlys['tabs']['custom'] = true;
}
elseif (!egw_vfs::is_writable($path))
{
@ -773,10 +794,10 @@ class filemanager_ui
$readonlys['#'.$name] = true;
}
}
$readonlys[$tabs]['eacl'] = true; // eacl off by default
$readonlys['tabs']['eacl'] = true; // eacl off by default
if ($content['is_dir'])
{
$readonlys[$tabs]['preview'] = true; // no preview tab for dirs
$readonlys['tabs']['preview'] = true; // no preview tab for dirs
$sel_options['rights']=$sel_options['owner']=$sel_options['group']=$sel_options['other'] = array(
7 => lang('Display and modification of content'),
5 => lang('Display of content'),
@ -784,7 +805,7 @@ class filemanager_ui
);
if(($content['eacl'] = egw_vfs::get_eacl($content['path'])) !== false) // backend supports eacl
{
unset($readonlys[$tabs]['eacl']); // --> switch the tab on again
unset($readonlys['tabs']['eacl']); // --> switch the tab on again
foreach($content['eacl'] as &$eacl)
{
$eacl['path'] = parse_url($eacl['path'],PHP_URL_PATH);

View File

@ -2,7 +2,7 @@
/**
* eGroupWare - eTemplates for Application filemanager
* http://www.egroupware.org
* generated by soetemplate::dump4setup() 2009-02-26 16:26
* generated by soetemplate::dump4setup() 2009-03-19 16:18
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package filemanager
@ -25,6 +25,17 @@ $templ_data[] = array('name' => 'filemanager.file','template' => '','lang' => ''
display: none;
}','modified' => '1223224423',);
$templ_data[] = array('name' => 'filemanager.file','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:3:"msg";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:3:"tab";s:5:"label";s:54:"General|Permissions|Extended ACL|Preview|Custom fields";s:4:"name";s:38:"tabs=general|perms|eacl|preview|custom";s:4:"span";s:3:"all";}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:3:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";}i:2;a:3:{s:4:"type";s:6:"button";s:4:"name";s:13:"button[apply]";s:5:"label";s:5:"Apply";}i:3;a:4:{s:4:"type";s:10:"buttononly";s:5:"label";s:6:"Cancel";s:4:"name";s:14:"button[cancel]";s:7:"onclick";s:15:"window.close();";}}i:2;a:6:{s:4:"type";s:10:"buttononly";s:5:"label";s:9:"Superuser";s:5:"align";s:5:"right";s:4:"help";s:48:"Enter setup user and password to get root rights";s:7:"onclick";s:121:"set_style_by_class(\'fieldset\',\'superuser\',\'display\',\'inline\'); document.getElementById(form::name(\'sudo[user]\')).focus();";s:4:"name";s:4:"sudo";}}}i:4;a:1:{s:1:"A";a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:29:"Enter setup user and password";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:0:{}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"User";s:4:"size";s:13:",,,sudo[user]";}s:1:"B";a:2:{s:4:"type";s:4:"text";s:4:"name";s:10:"sudo[user]";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:8:"Password";s:4:"size";s:15:",,,sudo[passwd]";}s:1:"B";a:2:{s:4:"type";s:6:"passwd";s:4:"name";s:12:"sudo[passwd]";}}i:3;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Submit";s:4:"name";s:13:"button[setup]";}}}s:7:"options";a:0:{}s:4:"rows";i:3;s:4:"cols";i:2;}s:4:"span";s:10:",superuser";}}}s:4:"rows";i:4;s:4:"cols";i:1;}}','size' => '','style' => '.eaclAccount select,.eaclRights select { width: 160px; }
.superuser {
position: absolute;
top: 130px;
left: 120px;
width: 200px;
background-color: white;
z-index: 1;
display: none;
}','modified' => '1223224423',);
$templ_data[] = array('name' => 'filemanager.file.custom','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:1:{s:2:"c1";s:4:",top";}i:1;a:1:{s:1:"A";a:1:{s:4:"type";s:12:"customfields";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:18:"450,300,,,10,,auto";}}','size' => '450,300,,,10,,auto','style' => '','modified' => '1223224487',);
$templ_data[] = array('name' => 'filemanager.file.eacl','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:2:"c1";s:4:",top";s:2:"c2";s:7:",bottom";s:2:"h2";s:11:",!@is_owner";}i:1;a:3:{s:1:"A";a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:4:"span";s:3:"all";s:5:"label";s:28:"Extended access control list";i:1;a:7:{s:4:"type";s:4:"grid";s:4:"size";s:17:"100%,200,,,,,auto";s:4:"data";a:3:{i:0;a:7:{s:1:"A";s:2:"80";s:1:"B";s:2:"80";s:1:"D";s:2:"16";s:2:"h2";s:4:",!@1";s:1:"C";s:3:"20%";s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Owner";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Rights";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Inherited";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:2;a:4:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:13:"${row}[owner]";s:8:"readonly";s:1:"1";}s:1:"B";a:3:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[rights]";s:8:"readonly";s:1:"1";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[path]";}s:1:"D";a:5:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:39:"delete[$row_cont[ino]-$row_cont[owner]]";s:7:"onclick";s:43:"return confirm(\'Delete this extended ACL\');";}}}s:4:"name";s:4:"eacl";s:4:"rows";i:2;s:4:"cols";i:4;s:7:"options";a:3:{i:0;s:4:"100%";i:1;s:3:"200";i:6;s:4:"auto";}}}s:1:"B";a:1:{s:4:"type";s:5:"label";}s:1:"C";a:1:{s:4:"type";s:5:"label";}}i:2;a:3:{s:1:"A";a:5:{s:4:"type";s:14:"select-account";s:4:"size";s:15:"select one,both";s:4:"name";s:11:"eacl[owner]";s:4:"span";s:12:",eaclAccount";s:5:"label";s:5:"Owner";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:4:"name";s:12:"eacl[rights]";s:4:"span";s:11:",eaclRights";s:5:"label";s:6:"Rights";}s:1:"C";a:3:{s:4:"type";s:6:"button";s:5:"label";s:3:"Add";s:4:"name";s:12:"button[eacl]";}}}s:4:"rows";i:2;s:4:"cols";i:3;s:4:"size";s:12:"450,300,,,10";s:7:"options";a:3:{i:0;s:3:"450";i:1;s:3:"300";i:4;s:2:"10";}}}','size' => '450,300,,,10','style' => '','modified' => '1207724932',);
@ -33,6 +44,8 @@ $templ_data[] = array('name' => 'filemanager.file.general','template' => '','lan
$templ_data[] = array('name' => 'filemanager.file.general','template' => '','lang' => '','group' => '0','version' => '1.5.003','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:9:{i:0;a:2:{s:1:"A";s:2:"80";s:2:"h1";s:2:"60";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"image";s:4:"name";s:4:"icon";s:4:"span";s:9:",mimeHuge";s:5:"align";s:6:"center";}s:1:"B";a:4:{s:4:"type";s:4:"text";s:4:"name";s:4:"name";s:6:"needed";s:1:"1";s:4:"span";s:9:",fileName";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"hrule";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:4:"mime";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Directory";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:3:"dir";}}i:5;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Size";}s:1:"B";a:3:{s:4:"type";s:8:"vfs-size";s:4:"name";s:4:"size";s:4:"size";s:1:"1";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Created";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"ctime";s:8:"readonly";s:1:"1";}}i:7;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Modified";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"mtime";s:8:"readonly";s:1:"1";}}i:8;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:10:",,,comment";s:5:"label";s:7:"Comment";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"name";s:7:"comment";s:4:"span";s:8:",comment";}}}s:4:"rows";i:8;s:4:"cols";i:2;s:4:"size";s:12:"450,300,,,10";s:7:"options";a:3:{i:0;s:3:"450";i:1;s:3:"300";i:4;s:2:"10";}}}','size' => '450,300,,,10','style' => '','modified' => '1204554817',);
$templ_data[] = array('name' => 'filemanager.file.general','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:10:{i:0;a:4:{s:1:"A";s:2:"80";s:2:"h1";s:2:"60";s:2:"h3";s:10:",!@is_link";s:2:"h6";s:9:",@is_link";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"image";s:4:"name";s:4:"icon";s:4:"span";s:9:",mimeHuge";s:5:"align";s:6:"center";}s:1:"B";a:4:{s:4:"type";s:4:"text";s:4:"name";s:4:"name";s:6:"needed";s:1:"1";s:4:"span";s:9:",fileName";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"hrule";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"Link";s:4:"size";s:10:",,,symlink";}s:1:"B";a:4:{s:4:"type";s:4:"text";s:4:"span";s:9:",fileName";s:4:"name";s:7:"symlink";s:8:"readonly";s:1:"1";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:4:"mime";}}i:5;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Directory";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:3:"dir";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Size";}s:1:"B";a:3:{s:4:"type";s:8:"vfs-size";s:4:"name";s:4:"size";s:4:"size";s:1:"1";}}i:7;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Created";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"ctime";s:8:"readonly";s:1:"1";}}i:8;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Modified";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"mtime";s:8:"readonly";s:1:"1";}}i:9;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:10:",,,comment";s:5:"label";s:7:"Comment";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"name";s:7:"comment";s:4:"span";s:8:",comment";}}}s:4:"rows";i:9;s:4:"cols";i:2;s:4:"size";s:12:"450,300,,,10";s:7:"options";a:3:{i:0;s:3:"450";i:1;s:3:"300";i:4;s:2:"10";}}}','size' => '450,300,,,10','style' => '','modified' => '1204554817',);
$templ_data[] = array('name' => 'filemanager.file.perms','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h3";s:9:",!@is_dir";}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:12:"Accessrights";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:3:{s:1:"A";s:2:"80";s:2:"h5";s:2:",1";s:2:"h4";s:8:",@is_dir";}i:1;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Owner";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"perms[owner]";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Group";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"perms[group]";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Other";}s:1:"B";a:2:{s:4:"type";s:6:"select";s:4:"name";s:12:"perms[other]";}}i:4;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:8:"checkbox";s:5:"label";s:10:"Executable";s:4:"name";s:17:"perms[executable]";}}i:5;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:8:"checkbox";s:5:"label";s:43:"Only owner can rename or delete the content";s:4:"name";s:13:"perms[sticky]";}}}s:4:"rows";i:5;s:4:"cols";i:2;s:7:"options";a:0:{}}}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:5:"Owner";i:1;a:5:{s:4:"type";s:4:"grid";s:7:"options";a:0:{}s:4:"data";a:3:{i:0;a:1:{s:1:"A";s:2:"80";}i:1;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"User";}s:1:"B";a:4:{s:4:"type";s:14:"select-account";s:4:"size";s:13:"root,accounts";s:4:"name";s:3:"uid";s:5:"label";s:12:"@ro_uid_root";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Group";}s:1:"B";a:4:{s:4:"type";s:14:"select-account";s:4:"size";s:11:"root,groups";s:4:"name";s:3:"gid";s:5:"label";s:12:"@ro_gid_root";}}}s:4:"rows";i:2;s:4:"cols";i:2;}}}i:3;a:1:{s:1:"A";a:3:{s:4:"type";s:8:"checkbox";s:5:"label";s:43:"Modify all Subdirectories and their content";s:4:"name";s:11:"modify_subs";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:4:"size";s:12:"450,300,,,10";s:7:"options";a:3:{i:0;s:3:"450";i:1;s:3:"300";i:4;s:2:"10";}}}','size' => '450,300,,,10','style' => '','modified' => '1204567746',);
$templ_data[] = array('name' => 'filemanager.file.preview','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:5:{s:2:"c1";s:4:",top";s:2:"h1";s:16:",!@mime=/^image/";s:2:"h3";s:22:",@mime=/^(image|text)/";s:2:"h2";s:18:"280,!@text_content";s:2:"c2";s:4:",top";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:5:"image";s:4:"name";s:4:"link";s:4:"span";s:13:",previewImage";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:8:"textarea";s:4:"name";s:12:"text_content";s:4:"span";s:12:",previewText";s:8:"readonly";s:1:"1";}}i:3;a:1:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:20:"No preview available";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:4:"size";s:18:"450,300,,,10,,auto";s:7:"options";a:4:{i:0;s:3:"450";i:1;s:3:"300";i:6;s:4:"auto";i:4;s:2:"10";}}}','size' => '450,300,,,10,,auto','style' => '','modified' => '1204567479',);
@ -41,6 +54,8 @@ $templ_data[] = array('name' => 'filemanager.index','template' => '','lang' => '
$templ_data[] = array('name' => 'filemanager.index','template' => '','lang' => '','group' => '0','version' => '1.6.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:2:{s:1:"A";s:3:"250";s:2:"h1";s:10:",!@nm[msg]";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:7:"nm[msg]";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:11:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"8";i:1;a:4:{s:4:"type";s:6:"button";s:4:"size";s:4:"goup";s:5:"label";s:2:"Up";s:4:"name";s:10:"button[up]";}i:2;a:4:{s:4:"type";s:6:"button";s:4:"name";s:12:"button[home]";s:4:"size";s:6:"gohome";s:5:"label";s:25:"Go to your home directory";}s:4:"span";s:3:"all";i:3;a:6:{s:4:"type";s:4:"text";s:4:"name";s:8:"nm[path]";s:4:"size";s:2:"80";s:5:"label";s:4:"Path";s:8:"onchange";i:1;s:4:"span";s:8:",address";}i:4;a:4:{s:4:"type";s:6:"button";s:4:"name";s:10:"button[go]";s:4:"size";s:9:"key_enter";s:5:"label";s:5:"Go to";}i:5;a:2:{s:4:"type";s:5:"image";s:4:"name";s:15:"buttonseparator";}i:6;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:13:"Edit settings";s:4:"name";s:23:"edit[{$cont[nm][path]}]";s:4:"help";s:39:"Rename, change permissions or ownership";s:7:"onclick";s:194:"window.open(egw::link(\'/index.php\',\'menuaction=filemanager.filemanager_ui.file&path={$cont[nm][path]}\'),\'fileprefs\',\'dependent=yes,width=495,height=425,scrollbars=yes,status=yes\'); return false;";}i:7;a:5:{s:4:"type";s:6:"button";s:4:"name";s:17:"button[createdir]";s:4:"size";s:16:"button_createdir";s:5:"label";s:16:"Create directory";s:7:"onclick";s:128:"var dir = prompt(egw::lang(\'New directory\')); if (!dir) return false; document.getElementById(form::name(\'nm[path]\')).value=dir;";}i:8;a:4:{s:4:"type";s:6:"button";s:4:"name";s:13:"button[paste]";s:4:"size";s:9:"editpaste";s:4:"help";s:20:"$cont[paste_tooltip]";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:9:"nextmatch";s:4:"size";s:22:"filemanager.index.rows";s:4:"span";s:3:"all";s:4:"name";s:2:"nm";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:4;a:2:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:4:"file";s:4:"name";s:8:"upload[]";s:4:"help";s:42:"Select file to upload in current directory";s:8:"onchange";s:99:"xajax_doXMLHTTP(\'filemanager_ui::ajax_check_upload_target\',this.id,this.value,\'{$cont[nm][path]}\');";}i:2;a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Upload";s:4:"name";s:14:"button[upload]";}}s:1:"B";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:5:"align";s:5:"right";i:1;a:4:{s:4:"type";s:6:"select";s:4:"name";s:6:"action";s:4:"size";s:16:"Select action...";s:8:"onchange";i:1;}i:2;a:8:{s:4:"type";s:6:"button";s:4:"size";s:9:"arrow_ltr";s:5:"label";s:9:"Check all";s:4:"name";s:9:"check_all";s:4:"help";s:9:"Check all";s:7:"onclick";s:70:"toggle_all(this.form,form::name(\'nm[rows][checked][]\')); return false;";s:6:"needed";s:1:"1";s:4:"span";s:14:",checkAllArrow";}}}}s:4:"rows";i:4;s:4:"cols";i:2;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1235658193',);
$templ_data[] = array('name' => 'filemanager.index','template' => '','lang' => '','group' => '0','version' => '1.7.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:2:{s:1:"A";s:3:"250";s:2:"h1";s:10:",!@nm[msg]";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:7:"nm[msg]";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:12:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"9";i:1;a:4:{s:4:"type";s:6:"button";s:4:"size";s:4:"goup";s:5:"label";s:2:"Up";s:4:"name";s:10:"button[up]";}i:2;a:4:{s:4:"type";s:6:"button";s:4:"name";s:12:"button[home]";s:4:"size";s:6:"gohome";s:5:"label";s:25:"Go to your home directory";}s:4:"span";s:3:"all";i:3;a:6:{s:4:"type";s:4:"text";s:4:"name";s:8:"nm[path]";s:4:"size";s:2:"80";s:5:"label";s:4:"Path";s:8:"onchange";i:1;s:4:"span";s:8:",address";}i:4;a:4:{s:4:"type";s:6:"button";s:4:"name";s:10:"button[go]";s:4:"size";s:9:"key_enter";s:5:"label";s:5:"Go to";}i:5;a:2:{s:4:"type";s:5:"image";s:4:"name";s:15:"buttonseparator";}i:6;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:13:"Edit settings";s:4:"name";s:23:"edit[{$cont[nm][path]}]";s:4:"help";s:39:"Rename, change permissions or ownership";s:7:"onclick";s:194:"window.open(egw::link(\'/index.php\',\'menuaction=filemanager.filemanager_ui.file&path={$cont[nm][path]}\'),\'fileprefs\',\'dependent=yes,width=495,height=425,scrollbars=yes,status=yes\'); return false;";}i:7;a:5:{s:4:"type";s:6:"button";s:4:"name";s:17:"button[createdir]";s:4:"size";s:16:"button_createdir";s:5:"label";s:16:"Create directory";s:7:"onclick";s:128:"var dir = prompt(egw::lang(\'New directory\')); if (!dir) return false; document.getElementById(form::name(\'nm[path]\')).value=dir;";}i:8;a:5:{s:4:"type";s:6:"button";s:4:"size";s:4:"link";s:5:"label";s:13:"Create a link";s:4:"name";s:15:"button[symlink]";s:7:"onclick";s:129:"var link = prompt(egw::lang(\'Link target\')); if (!link) return false; document.getElementById(form::name(\'nm[path]\')).value=link;";}i:9;a:4:{s:4:"type";s:6:"button";s:4:"name";s:13:"button[paste]";s:4:"size";s:9:"editpaste";s:4:"help";s:20:"$cont[paste_tooltip]";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:9:"nextmatch";s:4:"size";s:22:"filemanager.index.rows";s:4:"span";s:3:"all";s:4:"name";s:2:"nm";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:4;a:2:{s:1:"A";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:4:"file";s:4:"name";s:8:"upload[]";s:4:"help";s:42:"Select file to upload in current directory";s:8:"onchange";s:99:"xajax_doXMLHTTP(\'filemanager_ui::ajax_check_upload_target\',this.id,this.value,\'{$cont[nm][path]}\');";}i:2;a:3:{s:4:"type";s:6:"button";s:5:"label";s:6:"Upload";s:4:"name";s:14:"button[upload]";}}s:1:"B";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";s:5:"align";s:5:"right";i:1;a:4:{s:4:"type";s:6:"select";s:4:"name";s:6:"action";s:4:"size";s:16:"Select action...";s:8:"onchange";i:1;}i:2;a:8:{s:4:"type";s:6:"button";s:4:"size";s:9:"arrow_ltr";s:5:"label";s:9:"Check all";s:4:"name";s:9:"check_all";s:4:"help";s:9:"Check all";s:7:"onclick";s:70:"toggle_all(this.form,form::name(\'nm[rows][checked][]\')); return false;";s:6:"needed";s:1:"1";s:4:"span";s:14:",checkAllArrow";}}}}s:4:"rows";i:4;s:4:"cols";i:2;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1237464702',);
$templ_data[] = array('name' => 'filemanager.index.rows','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:6:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"B";s:3:"30%";s:1:"D";s:3:"120";s:1:"E";s:3:"120";s:1:"K";s:2:"70";}i:1;a:11:{s:1:"A";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Type";s:4:"name";s:4:"mime";s:5:"align";s:6:"center";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Name";s:4:"name";s:4:"name";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Size";s:4:"name";s:4:"size";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Modified";s:4:"name";s:5:"mtime";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"Created";s:4:"name";s:5:"ctime";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:11:"Permissions";s:4:"name";s:4:"mode";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"uid";s:5:"label";s:5:"Owner";}s:1:"H";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"gid";s:5:"label";s:5:"Group";}s:1:"I";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Comment";s:4:"name";s:7:"comment";}s:1:"J";a:3:{s:4:"type";s:22:"nextmatch-customfields";s:8:"readonly";s:1:"1";s:4:"name";s:12:"customfields";}s:1:"K";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";}i:2;a:8:{s:4:"type";s:6:"button";s:4:"size";s:5:"check";s:5:"label";s:9:"Check all";s:4:"name";s:9:"check_all";s:4:"help";s:9:"Check all";s:7:"onclick";s:60:"toggle_all(this.form,form::name(\'checked[]\')); return false;";s:6:"needed";s:1:"1";s:5:"align";s:5:"right";}}}i:2;a:11:{s:1:"A";a:4:{s:4:"type";s:5:"image";s:5:"label";s:15:"$row_cont[mime]";s:4:"name";s:12:"${row}[icon]";s:5:"align";s:6:"center";}s:1:"B";a:4:{s:4:"type";s:5:"label";s:4:"size";s:14:",@${row}[link]";s:4:"name";s:12:"${row}[name]";s:7:"no_lang";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:4:"name";s:13:"${row}[hsize]";s:5:"align";s:5:"right";}s:1:"D";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:13:"${row}[mtime]";s:8:"readonly";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:13:"${row}[ctime]";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:5:"label";s:5:"label";s:16:"$row_cont[perms]";s:4:"span";s:6:",perms";}s:1:"G";a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[user]";s:7:"no_lang";s:1:"1";}s:1:"H";a:3:{s:4:"type";s:5:"label";s:4:"name";s:13:"${row}[group]";s:7:"no_lang";s:1:"1";}s:1:"I";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[comment]";}s:1:"J";a:3:{s:4:"type";s:17:"customfields-list";s:8:"readonly";s:1:"1";s:4:"name";s:4:"$row";}s:1:"K";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:13:"Edit settings";s:4:"name";s:21:"edit[$row_cont[path]]";s:4:"help";s:39:"Rename, change permissions or ownership";s:7:"onclick";s:192:"window.open(egw::link(\'/index.php\',\'menuaction=filemanager.filemanager_ui.file&path=$row_cont[path]\'),\'fileprefs\',\'dependent=yes,width=495,height=400,scrollbars=yes,status=yes\'); return false;";}i:2;a:7:{s:4:"type";s:6:"button";s:4:"name";s:23:"delete[$row_cont[path]]";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"help";s:29:"Delete this file or directory";s:7:"onclick";s:48:"return confirm(\'Delete this file or directory\');";s:5:"align";s:6:"center";}i:3;a:4:{s:4:"type";s:8:"checkbox";s:4:"name";s:9:"checked[]";s:5:"align";s:5:"right";s:4:"size";s:15:"$row_cont[path]";}s:5:"align";s:5:"right";}}}s:4:"rows";i:2;s:4:"cols";i:11;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1204370567',);
$templ_data[] = array('name' => 'filemanager.index.rows','template' => '','lang' => '','group' => '0','version' => '1.5.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:6:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"B";s:3:"30%";s:1:"D";s:3:"120";s:1:"E";s:3:"120";s:1:"K";s:2:"70";}i:1;a:11:{s:1:"A";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Type";s:4:"name";s:4:"mime";s:5:"align";s:6:"center";}s:1:"B";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Name";s:4:"name";s:4:"name";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Size";s:4:"name";s:4:"size";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Modified";s:4:"name";s:5:"mtime";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"Created";s:4:"name";s:5:"ctime";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:11:"Permissions";s:4:"name";s:4:"mode";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"uid";s:5:"label";s:5:"Owner";}s:1:"H";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"gid";s:5:"label";s:5:"Group";}s:1:"I";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Comment";s:4:"name";s:7:"comment";}s:1:"J";a:3:{s:4:"type";s:22:"nextmatch-customfields";s:8:"readonly";s:1:"1";s:4:"name";s:12:"customfields";}s:1:"K";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";}i:2;a:8:{s:4:"type";s:6:"button";s:4:"size";s:5:"check";s:5:"label";s:9:"Check all";s:4:"name";s:9:"check_all";s:4:"help";s:9:"Check all";s:7:"onclick";s:60:"toggle_all(this.form,form::name(\'checked[]\')); return false;";s:6:"needed";s:1:"1";s:5:"align";s:5:"right";}}}i:2;a:11:{s:1:"A";a:3:{s:4:"type";s:8:"vfs-mime";s:4:"name";s:12:"${row}[path]";s:5:"align";s:6:"center";}s:1:"B";a:3:{s:4:"type";s:3:"vfs";s:4:"name";s:4:"$row";s:7:"no_lang";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:8:"vfs-size";s:4:"name";s:12:"${row}[size]";s:5:"align";s:5:"right";}s:1:"D";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:13:"${row}[mtime]";s:8:"readonly";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:13:"${row}[ctime]";s:8:"readonly";s:1:"1";}s:1:"F";a:2:{s:4:"type";s:8:"vfs-mode";s:4:"name";s:12:"${row}[mode]";}s:1:"G";a:3:{s:4:"type";s:7:"vfs-uid";s:4:"name";s:11:"${row}[uid]";s:7:"no_lang";s:1:"1";}s:1:"H";a:3:{s:4:"type";s:7:"vfs-gid";s:4:"name";s:11:"${row}[gid]";s:7:"no_lang";s:1:"1";}s:1:"I";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[comment]";}s:1:"J";a:3:{s:4:"type";s:17:"customfields-list";s:8:"readonly";s:1:"1";s:4:"name";s:4:"$row";}s:1:"K";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:13:"Edit settings";s:4:"name";s:21:"edit[$row_cont[path]]";s:4:"help";s:39:"Rename, change permissions or ownership";s:7:"onclick";s:192:"window.open(egw::link(\'/index.php\',\'menuaction=filemanager.filemanager_ui.file&path=$row_cont[path]\'),\'fileprefs\',\'dependent=yes,width=495,height=425,scrollbars=yes,status=yes\'); return false;";}i:2;a:7:{s:4:"type";s:6:"button";s:4:"name";s:23:"delete[$row_cont[path]]";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"help";s:29:"Delete this file or directory";s:7:"onclick";s:48:"return confirm(\'Delete this file or directory\');";s:5:"align";s:6:"center";}i:3;a:4:{s:4:"type";s:8:"checkbox";s:4:"name";s:9:"checked[]";s:5:"align";s:5:"right";s:4:"size";s:15:"$row_cont[path]";}s:5:"align";s:5:"right";}}}s:4:"rows";i:2;s:4:"cols";i:11;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1204370567',);

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!-- $Id$ -->
<overlay>
<template id="filemanager.file.general" template="" lang="" group="0" version="1.5.003">
<template id="filemanager.file.general" template="" lang="" group="0" version="1.7.001">
<grid width="450" height="300" spacing="10">
<columns>
<column width="80"/>
@ -15,6 +15,10 @@
<row>
<hrule span="all"/>
</row>
<row disabled="!@is_link">
<description value="Link" options=",,,symlink"/>
<textbox class="fileName" id="symlink" readonly="true"/>
</row>
<row>
<description value="Type"/>
<description id="mime"/>
@ -23,7 +27,7 @@
<description value="Directory"/>
<description id="dir"/>
</row>
<row>
<row disabled="@is_link">
<description value="Size"/>
<vfs-size id="size" options="1"/>
</row>
@ -199,7 +203,7 @@
</rows>
</grid>
</template>
<template id="filemanager.file" template="" lang="" group="0" version="1.5.004">
<template id="filemanager.file" template="" lang="" group="0" version="1.7.001">
<grid>
<columns>
<column/>
@ -209,7 +213,7 @@
<description span="all" class="redItalic" id="msg"/>
</row>
<row>
<tabbox span="all">
<tabbox id="tabs" span="all">
<tabs>
<tab label="General" statustext=""/>
<tab label="Permissions" statustext=""/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

View File

@ -53,7 +53,7 @@
</rows>
</grid>
</template>
<template id="filemanager.index" template="" lang="" group="0" version="1.6.001">
<template id="filemanager.index" template="" lang="" group="0" version="1.7.001">
<grid width="100%">
<columns>
<column width="250"/>
@ -73,6 +73,7 @@
<image src="buttonseparator"/>
<button image="edit" label="Edit settings" id="edit[{$cont[nm][path]}]" statustext="Rename, change permissions or ownership" onclick="window.open(egw::link('/index.php','menuaction=filemanager.filemanager_ui.file&amp;path={$cont[nm][path]}'),'fileprefs','dependent=yes,width=495,height=425,scrollbars=yes,status=yes'); return false;"/>
<button id="button[createdir]" image="button_createdir" label="Create directory" onclick="var dir = prompt(egw::lang('New directory')); if (!dir) return false; document.getElementById(form::name('nm[path]')).value=dir;"/>
<button image="link" label="Create a link" id="button[symlink]" onclick="var link = prompt(egw::lang('Link target')); if (!link) return false; document.getElementById(form::name('nm[path]')).value=link;"/>
<button id="button[paste]" image="editpaste" statustext="$cont[paste_tooltip]"/>
</hbox>
</row>

View File

@ -169,7 +169,7 @@ class egw_vfs extends vfs_stream_wrapper
* stat working on just the eGW VFS (alias of url_stat)
*
* @param string $path filename with absolute path in the eGW VFS
* @return resource
* @return array
*/
static function stat($path)
{
@ -184,6 +184,25 @@ class egw_vfs extends vfs_stream_wrapper
return $stat;
}
/**
* lstat (not resolving symbolic links) working on just the eGW VFS (alias of url_stat)
*
* @param string $path filename with absolute path in the eGW VFS
* @return array
*/
static function lstat($path)
{
if ($path[0] != '/')
{
throw new egw_exception_assertion_failed("File '$path' is not an absolute path!");
}
if (($stat = self::url_stat($path,STREAM_URL_STAT_LINK)))
{
$stat = array_slice($stat,13); // remove numerical indices 0-12
}
return $stat;
}
/**
* is_dir() version working only inside the vfs
*
@ -195,6 +214,16 @@ class egw_vfs extends vfs_stream_wrapper
return $path[0] == '/' && is_dir(self::SCHEME.'://default'.$path);
}
/**
* is_link() version working only inside the vfs
*
* @param string $path
* @return boolean
*/
static function is_link($path)
{
return $path[0] == '/' && is_link(self::SCHEME.'://default'.$path);
}
/**
* Mounts $url under $path in the vfs, called without parameter it returns the fstab
@ -272,12 +301,12 @@ class egw_vfs extends vfs_stream_wrapper
* - empty,size => (+|-|)N
* - cmin/mmin => (+|-|)N file/dir create/modified in the last N minutes
* - ctime/mtime => (+|-|)N file/dir created/modified in the last N days
* - depth => (+|-)N
* - url => false(default),true allow (and return) full URL's instead of VFS pathes (only set it, if you know what you doing securitywise!)
* - need_mime => false(default),true should we return the mime type
* - order => name order rows by name column
* - sort => (ASC|DESC) sort, default ASC
* - limit => N,[n=0] return N entries from position n on, which defaults to 0
* - follow => {true|false(default)} follow symlinks
* @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
* @param array $exec_params=null further params for exec as array, path is always the first param and stat the last!
@ -338,7 +367,7 @@ class egw_vfs extends vfs_stream_wrapper
{
if (!$url) $path = egw_vfs::PREFIX . $path;
$is_dir = is_dir($path);
$is_dir = is_dir($path) && ($options['follow'] || !is_link($path));
if (!isset($options['remove']))
{
$options['remove'] = count($base) == 1 ? count(explode('/',$path))-3+(int)(substr($path,-1)!='/') : 0;
@ -556,7 +585,7 @@ class egw_vfs extends vfs_stream_wrapper
{
$url = self::PREFIX . $url;
}
if (is_dir($url))
if (is_dir($url) && !is_link($url))
{
return rmdir($url);
}
@ -962,6 +991,8 @@ class egw_vfs extends vfs_stream_wrapper
/**
* Concat a relative path to an url, taking into account, that the url might already end with a slash or the path starts with one or is empty
*
* Also normalizing the path, as the relative path can contain ../
*
* @param string $url base url or path, might end in a /
* @param string $relative relative path to add to $url
* @return string
@ -970,7 +1001,37 @@ class egw_vfs extends vfs_stream_wrapper
{
list($url,$query) = explode('?',$url,2);
if (substr($url,-1) == '/') $url = substr($url,0,-1);
return ($relative === '' || $relative[0] == '/' ? $url.$relative : $url.'/'.$relative).($query ? '?'.$query : '');
$url = ($relative === '' || $relative[0] == '/' ? $url.$relative : $url.'/'.$relative);
// now normalize the path (remove "/something/..")
while (strpos($url,'..') !== false)
{
list($a,$b) = explode('..',$url,2);
$a = explode('/',$a);
array_pop($a);
array_pop($a);
$b = explode('/',$b);
if ($b[0] === '') array_shift($b);
$url = implode('/',array_merge($a,$b));
}
return $url.($query ? '?'.$query : '');
}
/**
* Build an url from it's components (reverse of parse_url)
*
* @param array $url_parts values for keys 'scheme', 'host', 'user', 'pass', 'query', 'fragment' (all but 'path' are optional)
* @return string
*/
static function build_url(array $url_parts)
{
$url = (!isset($url_parts['scheme'])?'':$url_parts['scheme'].'://'.
(!isset($url_parts['user'])?'':$url_parts['user'].(!isset($url_parts['pass'])?'':':'.$url_parts['pass']).'@').
$url_parts['host']).$url_parts['path'].
(!isset($url_parts['query'])?'':'?'.$url_parts['query']).
(!isset($url_parts['fragment'])?'':'?'.$url_parts['fragment']);
//error_log(__METHOD__.'('.array2string($url_parts).") = '".$url."'");
return $url;
}
/**

View File

@ -29,7 +29,7 @@
*
* The stream wrapper interface is according to the docu on php.net
*
* @link http://de.php.net/manual/de/function.stream-wrapper-register.php
* @link http://www.php.net/manual/en/function.stream-wrapper-register.php
* @ToDo versioning
*/
class sqlfs_stream_wrapper implements iface_stream_wrapper
@ -38,6 +38,10 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
* Mime type of directories, the old vfs uses 'Directory', while eg. WebDAV uses 'httpd/unix-directory'
*/
const DIR_MIME_TYPE = 'httpd/unix-directory';
/**
* Mime type for symlinks
*/
const SYMLINK_MIME_TYPE = 'application/x-symlink';
/**
* Scheme / protocoll used for this stream-wrapper
*/
@ -62,6 +66,10 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
* mode-bits, which have to be set for directories
*/
const MODE_DIR = 040000;
/**
* mode-bits, which have to be set for links
*/
const MODE_LINK = 0120000;
/**
* How much should be logged to the apache error-log
*
@ -69,7 +77,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
* 1 = only errors
* 2 = all function calls and errors (contains passwords too!)
*/
const LOG_LEVEL = 2;
const LOG_LEVEL = 1;
/**
* We do versioning AND store the content in the db, NOT YET IMPLEMENTED
@ -495,7 +503,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
$path = parse_url($url,PHP_URL_PATH);
if (!($stat = self::url_stat($path,0)) || !egw_vfs::check_access(dirname($path),egw_vfs::WRITABLE))
if (!($stat = self::url_stat($path,STREAM_URL_STAT_LINK)) || !egw_vfs::check_access(dirname($path),egw_vfs::WRITABLE))
{
self::_remove_password($url);
if (self::LOG_LEVEL) error_log(__METHOD__."($url) (type=$type) permission denied!");
@ -506,7 +514,10 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
if (($ret = $stmt->execute(array(':fs_id' => $stat['ino']))))
{
if (self::url2operation($url) == self::STORE2FS) unlink(self::_fs_path($stat['ino']));
if (self::url2operation($url) == self::STORE2FS && !($stat['mode'] & self::MODE_LINK))
{
unlink(self::_fs_path($stat['ino']));
}
// delete props
unset($stmt);
$stmt = self::$pdo->prepare('DELETE FROM '.self::PROPS_TABLE.' WHERE fs_id=?');
@ -1086,6 +1097,68 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
return true;
}
/**
* This method is called in response to readlink().
*
* @param string $url
* @return string|boolean content of the symlink or false if $url is no symlink (or not found)
*/
static function readlink($url)
{
if (self::LOG_LEVEL > 1) error_log(__METHOD__."('$url')");
$url_path = parse_url($url,PHP_URL_PATH);
if (!($lstat = self::url_stat($url_path,STREAM_URL_STAT_LINK)) || !($lstat['mode'] & self::MODE_LINK) ||
!($result = self::$pdo->query("SELECT fs_content FROM ".self::TABLE." WHERE fs_id=".(int)$lstat['ino'])))
{
return false;
}
return $result->fetchColumn();
}
/**
* Method called for symlink()
*
* @param string $target
* @param string $link
* @return boolean true on success false on error
*/
static function symlink($target,$link)
{
if (self::LOG_LEVEL > 1) error_log(__METHOD__."('$target','$link')");
if (self::url_stat($link,0) || !($dir = dirname($link)) ||
!egw_vfs::check_access($dir,egw_vfs::WRITABLE,$dir_stat=self::url_stat($dir,0)))
{
if (self::LOG_LEVEL > 0) error_log(__METHOD__."('$target','$link') returning false! (!stat('$link') || !is_writable('$dir'))");
return false; // $link already exists or parent dir does not
}
$stmt = self::$pdo->prepare($query='INSERT INTO '.self::TABLE.' (fs_name,fs_dir,fs_mode,fs_uid,fs_gid,fs_created,fs_modified,fs_creator,fs_mime,fs_size,fs_content'.
') VALUES (:fs_name,:fs_dir,:fs_mode,:fs_uid,:fs_gid,:fs_created,:fs_modified,:fs_creator,:fs_mime,:fs_size,:fs_content)');
$values = array(
'fs_name' => basename($link),
'fs_dir' => $dir_stat['ino'],
// we use the mode of the dir, so files in group dirs stay accessible by all members
'fs_mode' => ($dir_stat['mode'] & 0666),
// for the uid we use the uid of the dir if not 0=root or the current user otherwise
'fs_uid' => $dir_stat['uid'] ? $dir_stat['uid'] : egw_vfs::$user,
// we allways use the group of the dir
'fs_gid' => $dir_stat['gid'],
'fs_created' => self::_pdo_timestamp(time()),
'fs_modified' => self::_pdo_timestamp(time()),
'fs_creator' => egw_vfs::$user,
'fs_mime' => self::SYMLINK_MIME_TYPE,
'fs_size' => bytes($target),
'fs_content' => $target,
);
foreach($values as $name => &$val)
{
$stmt->bindParam(':'.$name,$val);
}
return !!$stmt->execute();
}
private static $extended_acl;
/**
@ -1330,7 +1403,8 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
'ino' => $info['fs_id'],
'name' => $info['fs_name'],
'mode' => $info['fs_mode'] |
($info['fs_mime'] == self::DIR_MIME_TYPE ? self::MODE_DIR : self::MODE_FILE), // required by the stream wrapper
($info['fs_mime'] == self::DIR_MIME_TYPE ? self::MODE_DIR :
($info['fs_mime'] == self::SYMLINK_MIME_TYPE ? self::MODE_LINK : self::MODE_FILE)), // required by the stream wrapper
'size' => $info['fs_size'],
'uid' => $info['fs_uid'],
'gid' => $info['fs_gid'],

View File

@ -49,6 +49,10 @@ class vfs_stream_wrapper implements iface_stream_wrapper
* @var mixed
*/
var $context;
/**
* mode-bits, which have to be set for links
*/
const MODE_LINK = 0120000;
/**
* Our fstab in the form mount-point => url
@ -101,11 +105,33 @@ class vfs_stream_wrapper implements iface_stream_wrapper
private static $wrappers;
/**
* Resolve the given path according to our fstab AND symlinks
*
* @param string $path
* @param boolean $file_exists=true true if file needs to exists, false if not
* @return string|boolean false if the url cant be resolved, should not happen if fstab has a root entry
*/
static function resolve_url_symlinks($path,$file_exists=true,$resolve_last_symlink=true)
{
if (!($stat = self::url_stat($path,$resolve_last_symlink?0:STREAM_URL_STAT_LINK)) && !$file_exists)
{
$ret = self::check_symlink_components($path,0,$url);
//error_log(__METHOD__."('$path',$file_exists) check_symlink_components()=$ret, url='$url'");
}
else
{
$url = $stat['url'];
}
//error_log(__METHOD__."($path,file_exists=$file_exists,resolve_last_symlink=$resolve_last_symlink) = '$url'");
return $url;
}
/**
* Resolve the given path according to our fstab
*
* @param string $path
* @return string/boolean false if the url cant be relsolved, should not happen if fstab has a root entry
* @return string|boolean false if the url cant be resolved, should not happen if fstab has a root entry
*/
static function resolve_url($path)
{
@ -176,7 +202,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
{
$this->opened_stream = null;
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path,$mode[0]=='r')))
{
return false;
}
@ -319,7 +345,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
static function unlink ( $path )
{
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path,true,false))) // true,false file need to exist, but do not resolve last component
{
return false;
}
@ -340,8 +366,8 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
static function rename ( $path_from, $path_to )
{
if (!($url_from = self::resolve_url($path_from)) ||
!($url_to = self::resolve_url($path_to)))
if (!($url_from = self::resolve_url_symlinks($path_from,true,false)) ||
!($url_to = self::resolve_url_symlinks($path_to,false)))
{
return false;
}
@ -361,7 +387,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
static function mkdir ( $path, $mode, $options )
{
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path,false))) // false = directory does not need to exists
{
return false;
}
@ -380,7 +406,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
static function rmdir ( $path, $options )
{
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path)))
{
return false;
}
@ -396,16 +422,17 @@ class vfs_stream_wrapper implements iface_stream_wrapper
* @param array $params first param has to be the path, otherwise we can not determine the correct wrapper
* @param boolean $fail_silent=false should only false be returned if function is not supported by the backend,
* or should an E_USER_WARNING error be triggered (default)
* @param int $path_param_key=0 key in params containing the path, default 0
* @return mixed return value of backend or false if function does not exist on backend
*/
static protected function _call_on_backend($name,$params,$fail_silent=false)
static protected function _call_on_backend($name,$params,$fail_silent=false,$path_param_key=0)
{
$pathes = $params[0];
$pathes = $params[$path_param_key];
$scheme2urls = array();
foreach(is_array($pathes) ? $pathes : array($pathes) as $path)
{
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path,false,false)))
{
return false;
}
@ -423,11 +450,11 @@ class vfs_stream_wrapper implements iface_stream_wrapper
}
if (!is_array($pathes))
{
$params[0] = $url;
$params[$path_param_key] = $url;
return call_user_func_array(array($scheme.'_stream_wrapper',$name),$params);
}
$params[0] = $urls;
$params[$path_param_key] = $urls;
if (!is_array($r = call_user_func_array(array($scheme.'_stream_wrapper',$name),$params)))
{
return $r;
@ -445,29 +472,6 @@ class vfs_stream_wrapper implements iface_stream_wrapper
}
}
return $ret;
// old, non array aware code
if (!($url = self::resolve_url($params[0])))
{
return false;
}
if (($scheme = parse_url($url,PHP_URL_SCHEME)))
{
if (!class_exists($class = $scheme.'_stream_wrapper') || !method_exists($class,$name))
{
if (!$fail_silent) trigger_error("Can't $name for scheme $scheme!\n",E_USER_WARNING);
return false;
}
$params[0] = $url;
return call_user_func_array(array($scheme.'_stream_wrapper',$name),$params);
}
// call the filesystem specific function
if (!function_exists($name))
{
return false;
}
return $name($url,$time);
}
/**
@ -525,6 +529,33 @@ class vfs_stream_wrapper implements iface_stream_wrapper
return self::_call_on_backend('chgrp',array($path,$group));
}
/**
* Returns the target of a symbolic link
*
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
*
* @param string $path
* @return string|boolean link-data or false if no link
*/
static function readlink($path)
{
return self::_call_on_backend('readlink',array($path));
}
/**
* Creates a symbolic link
*
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
*
* @param string $target target of the link
* @param string $link path of the link to create
* @return boolean true on success, false on error
*/
static function symlink($target,$link)
{
return self::_call_on_backend('symlink',array($target,$link),false,1); // 1=path is in $link!
}
/**
* This is not (yet) a stream-wrapper function, but it's necessary and can be used static
*
@ -539,7 +570,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
static function mime_content_type($path)
{
if (!($url = self::resolve_url($path)))
if (!($url = self::resolve_url_symlinks($path)))
{
return false;
}
@ -591,10 +622,11 @@ class vfs_stream_wrapper implements iface_stream_wrapper
$this->opened_dir = $this->extra_dirs = null;
$this->extra_dir_ptr = 0;
if (!($this->opened_dir_url = self::resolve_url($path)))
if (!($this->opened_dir_url = self::resolve_url_symlinks($path)))
{
return false;
}
if (!($this->opened_dir = opendir($this->opened_dir_url)))
{
//error_log(__METHOD__." dir failed: ".$this->opened_dir);
@ -641,9 +673,11 @@ class vfs_stream_wrapper implements iface_stream_wrapper
* - STREAM_URL_STAT_QUIET If this flag is set, your wrapper should not raise any errors. If this flag is not set,
* you are responsible for reporting errors using the trigger_error() function during stating of the path.
* stat triggers it's own warning anyway, so it makes no sense to trigger one by our stream-wrapper!
* @param boolean $try_create_home=true should a user home-directory be created automatic, if it does not exist
* @param boolean $check_symlink_components=true check if path contains symlinks in path components other then the last one
* @return array
*/
static function url_stat ( $path, $flags )
static function url_stat ( $path, $flags, $try_create_home=true, $check_symlink_components=true )
{
//error_log(__METHOD__."('$path',$flags)");
@ -652,8 +686,30 @@ class vfs_stream_wrapper implements iface_stream_wrapper
return false;
}
//error_log(__METHOD__."('$path',$flags) calling stat($url)");
$stat = @stat($url); // suppressed the stat failed warnings
if ($flags & STREAM_URL_STAT_LINK)
{
$stat = @lstat($url); // suppressed the stat failed warnings
}
else
{
$stat = @stat($url); // suppressed the stat failed warnings
if ($stat && ($stat['mode'] & self::MODE_LINK) && ($l=$lpath = self::readlink($url)))
{
if ($lpath[0] != '/') // contact releative path
{
$url = egw_vfs::concat($url,'../'.$lpath);
}
else // or replace absolute path in url
{
$url_parts = parse_url($url);
$url_parts['path'] = $lpath;
$url = egw_vfs::build_url($url_parts);
}
//error_log(__METHOD__."($path,$flags) symlink found and resolved to $url");
$stat = @stat($url);
}
}
// check if a failed url_stat was for a home dir, in that case silently create it
if (!$stat && dirname(parse_url($path,PHP_URL_PATH)) == '/home' && ($id = $GLOBALS['egw']->accounts->name2id(basename($path))))
{
@ -664,7 +720,15 @@ class vfs_stream_wrapper implements iface_stream_wrapper
'account_name' => basename($path),
);
call_user_func(array('vfs_home_hooks',$hook_data['location']),$hook_data);
$stat = @stat($url);
$stat = self::url_stat($path,$flags,false);
}
if (!$stat && $check_symlink_components) // check if there's a symlink somewhere inbetween the path
{
$stat = self::check_symlink_components($path,$flags,$urlx=$url);
}
elseif(is_array($stat) && !isset($stat['url']))
{
$stat['url'] = $url;
}
return $stat;
@ -678,6 +742,52 @@ class vfs_stream_wrapper implements iface_stream_wrapper
return $stat;
}
/**
* Check if path (which fails the stat call) contains symlinks in path-components other then the last one
*
* @param string $path
* @param int $flags=0 see url_stat
* @param string &$url=null already resolved path
* @return array|boolean stat array or false if not found
*/
static private function check_symlink_components($path,$flags=0,&$url=null)
{
if (is_null($url) && !($url = self::resolve_url($path)))
{
return false;
}
//echo "<p>".__METHOD__."('$path',$flags,'$url'): ".function_backtrace(1)."</p>\n";
while (($rel_path = egw_vfs::basename($url).($rel_path ? '/'.$rel_path : '')) &&
($url = egw_vfs::dirname($url)))
{
$stat = self::url_stat($url,0,false,false);
//echo "<p>rel_path='$rel_path', stat(url='$url')=".array2string($stat)."</p>\n";
if (($stat = self::url_stat($url,0,false,false)))
{
if (is_link($url) && ($lpath = self::readlink($url)))
{
//echo "<p>rel_path='$rel_path', url='$url': lpath='$lpath'\n";
if ($lpath[0] != '/')
{
$url = egw_vfs::concat($url,'../'.$lpath);
}
else
{
$url_parts = parse_url($url);
$url_parts['path'] = $lpath;
$url = egw_vfs::build_url($url_parts);
}
$url = egw_vfs::concat($url,$rel_path);
//echo "--> <b>url='$url'</b></p>\n";
return self::url_stat($url,$flags);
}
$url = egw_vfs::concat($url,$rel_path);
return null;
}
}
return false; // $path does not exist
}
/**
* This method is called in response to readdir().
*