mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 01:13:25 +01:00
first work on UI for a new filemanager and some vfs bugfixes and improvments
This commit is contained in:
parent
9887c58b4d
commit
4df4fd9f06
@ -21,7 +21,7 @@ if (isset($_SERVER['HTTP_HOST'])) // security precaution: forbit calling ls as w
|
||||
}
|
||||
|
||||
/**
|
||||
* callback if the session-check fails, redirects via xajax to login.php
|
||||
* callback if the session-check fails, creates session from user/passwd in $GLOBALS['egw_login_data']
|
||||
*
|
||||
* @param array &$account account_info with keys 'login', 'passwd' and optional 'passwd_type'
|
||||
* @return boolean/string true if we allow the access and account is set, a sessionid or false otherwise
|
||||
@ -58,7 +58,7 @@ function usage($action=null,$ret=0)
|
||||
echo "\t$cmd chmod [-r|--recursive] mode=[ugoa]*[+-=][rwx]+,... 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 find URL [URL2 ...] [-type (d|f)][-dirs_last][-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)\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)\n";
|
||||
echo "\t$cmd mount URL [path] (without path prints out the mounts)\n";
|
||||
echo "\t$cmd umount URL|path\n";
|
||||
|
||||
@ -92,13 +92,13 @@ while(!is_null($option = array_shift($argv)))
|
||||
default:
|
||||
if ($cmd == 'find')
|
||||
{
|
||||
if (!in_array($option,array('-type','-dirs_last','-name','-path',
|
||||
if (!in_array($option,array('-type','-depth','-mindepth','-maxdepth','-name','-path',
|
||||
'-uid','-user','-nouser','-gid','-group','-nogroup','-mime',
|
||||
'-empty','-size','-cmin','-ctime','-mmin','-mtime')))
|
||||
{
|
||||
usage();
|
||||
}
|
||||
if (in_array($option,array('-empty','-dirs_last','-nouser','-nogroup')))
|
||||
if (in_array($option,array('-empty','-depth','-nouser','-nogroup')))
|
||||
{
|
||||
$find_options[substr($option,1)] = true;
|
||||
}
|
||||
@ -328,7 +328,7 @@ switch($cmd)
|
||||
{
|
||||
load_wrapper($url);
|
||||
array_unshift($argv,$url);
|
||||
egw_vfs::find($argv,array('dirs_last'=>true),'do_stat',array($long,$numeric,true));
|
||||
egw_vfs::find($argv,array('url'=>true,),'do_stat',array($long,$numeric,true));
|
||||
$argv = array();
|
||||
}
|
||||
elseif (is_dir($url) && ($dir = opendir($url)))
|
||||
@ -431,6 +431,12 @@ function load_wrapper($url)
|
||||
}
|
||||
set_exception_handler('cli_exception_handler'); // otherwise we get html!
|
||||
}
|
||||
$cmd = $GLOBALS['cmd'];
|
||||
if (!in_array($cmd,array('ls','find','mount','umount')) && $GLOBALS['egw_info']['server']['files_dir'] && !is_writable($GLOBALS['egw_info']['server']['files_dir']))
|
||||
{
|
||||
echo "\nError: eGroupWare's files directory {$GLOBALS['egw_info']['server']['files_dir']} is NOT writable by the user running ".basename(__FILE__)."!\n".
|
||||
"--> Please run it as the same user the webserver uses or root, otherwise the $cmd command will fail!\n\n";
|
||||
}
|
||||
}
|
||||
require_once(EGW_API_INC.'/class.'.$scheme.'_stream_wrapper.inc.php');
|
||||
break;
|
||||
@ -549,7 +555,7 @@ function do_cp($argv,$recursive=false,$perms=false)
|
||||
{
|
||||
if (is_dir($from) && (!file_exists($to) || is_dir($to)) && $recursive && class_exists('egw_vfs'))
|
||||
{
|
||||
foreach(egw_vfs::find($from) as $f)
|
||||
foreach(egw_vfs::find($from,array('url' => true)) as $f)
|
||||
{
|
||||
$t = $to.substr($f,strlen($from));
|
||||
if (is_dir($f))
|
||||
@ -629,6 +635,8 @@ function do_find($bases,$options)
|
||||
{
|
||||
load_wrapper($url);
|
||||
}
|
||||
$options['url'] = true; // we use url's not vfs pathes in filemanager/cli.php
|
||||
|
||||
foreach(egw_vfs::find($bases,$options) as $path)
|
||||
{
|
||||
echo "$path\n";
|
||||
|
@ -28,7 +28,8 @@ class filemanager_hooks
|
||||
'Search',
|
||||
'text' => 'Search',
|
||||
'link' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'filemanager.uifilemanager.index', 'action'=>'search')),
|
||||
)
|
||||
),
|
||||
'New GUI' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'filemanager.filemanager_ui.index')),
|
||||
);
|
||||
display_sidebox($appname,$title,$file);
|
||||
}
|
||||
|
376
filemanager/inc/class.filemanager_ui.inc.php
Normal file
376
filemanager/inc/class.filemanager_ui.inc.php
Normal file
@ -0,0 +1,376 @@
|
||||
<?php
|
||||
/**
|
||||
* Filemanager - user interface
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package admin
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2008 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
class filemanager_ui
|
||||
{
|
||||
/**
|
||||
* Methods callable via menuaction
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $public_functions = array(
|
||||
'index' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Main filemanager page
|
||||
*
|
||||
* @param array $content=null
|
||||
* @param string $msg=null
|
||||
*/
|
||||
function index($content=null,$msg=null)
|
||||
{
|
||||
$tpl = new etemplate('filemanager.index');
|
||||
|
||||
//_debug_array($content);
|
||||
|
||||
if (!is_array($content))
|
||||
{
|
||||
$content = array(
|
||||
'nm' => $GLOBALS['egw']->session->appsession('index','filemanager'),
|
||||
);
|
||||
if (!is_array($content['nm']))
|
||||
{
|
||||
$content['nm'] = array(
|
||||
'get_rows' => 'filemanager.filemanager_ui.get_rows', // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
|
||||
// 'filter_label' => // I label for filter (optional)
|
||||
// 'filter_help' => // I help-msg for filter (optional)
|
||||
'no_filter' => True, // I disable the 1. filter
|
||||
'no_filter2' => True, // I disable the 2. filter (params are the same as for filter)
|
||||
'no_cat' => True, // I disable the cat-selectbox
|
||||
// 'cat_app' => // I application the cat's should be from, default app in get_rows
|
||||
// 'template' => // I template to use for the rows, if not set via options
|
||||
// 'header_left' => // I template to show left of the range-value, left-aligned (optional)
|
||||
// 'header_right' => // I template to show right of the range-value, right-aligned (optional)
|
||||
// 'bottom_too' => True// I show the nextmatch-line (arrows, filters, search, ...) again after the rows
|
||||
// 'never_hide' => True, // I never hide the nextmatch-line if less then maxmatch entrie
|
||||
// 'lettersearch' => True, // I show a lettersearch
|
||||
'searchletter' => false, // I0 active letter of the lettersearch or false for [all]
|
||||
'start' => 0, // IO position in list
|
||||
// 'num_rows' => // IO number of rows to show, defaults to maxmatches from the general prefs
|
||||
// 'cat_id' => // IO category, if not 'no_cat' => True
|
||||
// 'search' => // IO search pattern
|
||||
'order' => 'name', // IO name of the column to sort after (optional for the sortheaders)
|
||||
'sort' => 'ASC', // IO direction of the sort: 'ASC' or 'DESC'
|
||||
// 'col_filter' => // IO array of column-name value pairs (optional for the filterheaders)
|
||||
// 'filter' => // IO filter, if not 'no_filter' => True
|
||||
// 'filter_no_lang' => True// I set no_lang for filter (=dont translate the options)
|
||||
// 'filter_onchange'=> 'this.form.submit();'// I onChange action for filter, default: this.form.submit();
|
||||
// 'filter2' => // IO filter2, if not 'no_filter2' => True
|
||||
// 'filter2_no_lang'=> True// I set no_lang for filter2 (=dont translate the options)
|
||||
// 'filter2_onchange'=> 'this.form.submit();'// I onChange action for filter, default: this.form.submit();
|
||||
'default_cols' => '!comment', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
|
||||
'csv_fields' => false, // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
|
||||
//or array with name=>label or name=>array('label'=>label,'type'=>type) pairs (type is a eT widget-type)
|
||||
'path' => '/home/'.$GLOBALS['egw_info']['user']['account_lid'],
|
||||
);
|
||||
}
|
||||
if (isset($_GET['path']) && ($path = $_GET['path']) && $path[0] == '/' && egw_vfs::is_dir($path))
|
||||
{
|
||||
$content['nm']['path'] = $path;
|
||||
}
|
||||
}
|
||||
$content['nm']['msg'] = $msg;
|
||||
|
||||
if ($content['action'] || $content['nm']['rows'])
|
||||
{
|
||||
if ($content['action'])
|
||||
{
|
||||
$content['nm']['msg'] = self::action($content['action'],$content['nm']['rows']['checked'],$content['nm']['path']);
|
||||
unset($content['action']);
|
||||
}
|
||||
elseif($content['nm']['rows']['delete'])
|
||||
{
|
||||
$content['nm']['msg'] = self::action('delete',array_keys($content['nm']['rows']['delete']),$content['nm']['path']);
|
||||
}
|
||||
unset($content['nm']['rows']);
|
||||
}
|
||||
$clipboard_files = $GLOBALS['egw']->session->appsession('clipboard_files','filemanager');
|
||||
|
||||
if ($content['button'])
|
||||
{
|
||||
if ($content['button'])
|
||||
{
|
||||
list($button) = each($content['button']);
|
||||
unset($content['button']);
|
||||
}
|
||||
switch($button)
|
||||
{
|
||||
case 'up':
|
||||
if ($content['nm']['path'] != '/')
|
||||
{
|
||||
$content['nm']['path'] = dirname($content['nm']['path']);
|
||||
}
|
||||
break;
|
||||
case 'home':
|
||||
$content['nm']['path'] = '/home/'.$GLOBALS['egw_info']['user']['account_lid'];
|
||||
break;
|
||||
case 'createdir':
|
||||
if ($content['nm']['path'][0] != '/')
|
||||
{
|
||||
$ses = $GLOBALS['egw']->session->appsession('index','filemanager');
|
||||
$old_path = $ses['path'];
|
||||
$content['nm']['path'] = $old_path.'/'.$content['nm']['path'];
|
||||
}
|
||||
if (!@egw_vfs::mkdir($content['nm']['path'],null,STREAM_MKDIR_RECURSIVE))
|
||||
{
|
||||
$content['nm']['msg'] = !egw_vfs::is_writable(dirname($content['nm']['path'])) ?
|
||||
lang('Permission denied!') : lang('Failed to create directory!');
|
||||
if (!$old_path)
|
||||
{
|
||||
$ses = $GLOBALS['egw']->session->appsession('index','filemanager');
|
||||
$old_path = $ses['path'];
|
||||
}
|
||||
$content['nm']['path'] = $old_path;
|
||||
}
|
||||
break;
|
||||
case 'paste':
|
||||
$clipboard_type = $GLOBALS['egw']->session->appsession('clipboard_type','filemanager');
|
||||
$content['nm']['msg'] = self::action($clipboard_type.'_paste',$clipboard_files,$content['nm']['path']);
|
||||
break;
|
||||
case 'upload':
|
||||
$to = $content['nm']['path'].'/'.$content['upload']['name'];
|
||||
if ($content['upload'] && is_uploaded_file($content['upload']['tmp_name']) &&
|
||||
(egw_vfs::is_writable($content['nm']['path']) || egw_vfs::is_writable($to)) &&
|
||||
copy($content['upload']['tmp_name'],egw_vfs::PREFIX.$to))
|
||||
{
|
||||
$content['nm']['msg'] = lang('File successful uploaded.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$content['nm']['msg'] = lang('Error uploading file!');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!egw_vfs::is_dir($content['nm']['path']))
|
||||
{
|
||||
$content['nm']['msg'] .= lang('Directory not found or no permission to access it!');
|
||||
}
|
||||
else
|
||||
{
|
||||
$dir_is_writable = egw_vfs::is_writable($content['nm']['path']);
|
||||
}
|
||||
//_debug_array($content);
|
||||
$readonlys['button[paste]'] = !$clipboard_files;
|
||||
$readonlys['button[createdir]'] = !$dir_is_writable;
|
||||
$readonlys['button[upload]'] = !$dir_is_writable;
|
||||
|
||||
if ($dir_is_writable) $sel_options['action']['delete'] = lang('Delete');
|
||||
$sel_options['action']['copy'] = lang('Copy to clipboard');
|
||||
if ($dir_is_writable) $sel_options['action']['cut'] = lang('Cut to clipboard');
|
||||
|
||||
$tpl->exec('filemanager.filemanager_ui.index',$content,$sel_options,$readonlys,array('nm' => $content['nm']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a certain action with the selected file
|
||||
*
|
||||
* @param string $action
|
||||
* @param array $selected selected pathes
|
||||
* @param mixed $dir=null current directory
|
||||
* @return string success or failure message displayed to the user
|
||||
*/
|
||||
static private function action($action,$selected,$dir=null)
|
||||
{
|
||||
//echo '<p>'.__METHOD__."($action,array(".implode(', ',$selected).",$dir)</p>\n";
|
||||
if (!count($selected))
|
||||
{
|
||||
return lang('You need to select some files first!');
|
||||
}
|
||||
$errs = $dirs = $files = 0;
|
||||
switch($action)
|
||||
{
|
||||
case 'delete':
|
||||
$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))
|
||||
{
|
||||
++$dirs;
|
||||
}
|
||||
elseif (!$is_dir && egw_vfs::unlink($path))
|
||||
{
|
||||
++$files;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$errs;
|
||||
}
|
||||
}
|
||||
if ($errs)
|
||||
{
|
||||
return lang('%1 errors deleteting (%2 directories and %3 files deleted)!',$errs,$dirs,$files);
|
||||
}
|
||||
if ($dirs)
|
||||
{
|
||||
return lang('%1 directories and %2 files deleted.',$dirs,$files);
|
||||
}
|
||||
return $files == 1 ? lang('File deleted.') : lang('%1 files deleted.',$files);
|
||||
|
||||
case 'copy':
|
||||
case 'cut':
|
||||
$GLOBALS['egw']->session->appsession('clipboard_files','filemanager',$selected);
|
||||
$GLOBALS['egw']->session->appsession('clipboard_type','filemanager',$action);
|
||||
return lang('%1 URLs %2 to clipboard.',count($selected),$action=='copy'?lang('copied'):lang('cut'));
|
||||
|
||||
case 'copy_paste':
|
||||
foreach($selected as $path)
|
||||
{
|
||||
if (!egw_vfs::is_dir($path))
|
||||
{
|
||||
$to = $dir.'/'.egw_vfs::basename($path);
|
||||
if (egw_vfs::copy($path,$to))
|
||||
{
|
||||
++$files;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$errs;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$len = strlen(dirname($path));
|
||||
foreach(egw_vfs::find($path) as $p)
|
||||
{
|
||||
$to = $dir.substr($p,$len);
|
||||
if (($is_dir = egw_vfs::is_dir($p)) && egw_vfs::mkdir($to,null,STREAM_MKDIR_RECURSIVE))
|
||||
{
|
||||
++$dirs;
|
||||
}
|
||||
elseif(!$is_dir && egw_vfs::copy($p,$to))
|
||||
{
|
||||
++$files;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$errs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($errs)
|
||||
{
|
||||
return lang('%1 errors copying (%2 diretories and %3 files copied)!',$errs,$dirs,$files);
|
||||
}
|
||||
return $dirs ? lang('%1 directories and %2 files copied.',$dirs,$files) : lang('%1 files copied.',$files);
|
||||
|
||||
case 'cut_paste':
|
||||
foreach($selected as $path)
|
||||
{
|
||||
$to = $dir.'/'.egw_vfs::basename($path);
|
||||
if (egw_vfs::rename($path,$to))
|
||||
{
|
||||
++$files;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$errs;
|
||||
}
|
||||
}
|
||||
$GLOBALS['egw']->session->appsession('clipboard_files','filemanager',false); // cant move again
|
||||
if ($errs)
|
||||
{
|
||||
return lang('%1 errors moving (%2 files moved)!',$errs,$files);
|
||||
}
|
||||
return lang('%1 files moved.',$files);
|
||||
}
|
||||
return "Unknown action '$action'!";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the closest mime icon
|
||||
*
|
||||
* @param string $mime_type
|
||||
* @param int $size=16
|
||||
* @return string
|
||||
*/
|
||||
static private function mime_icon($mime_type, $size=16)
|
||||
{
|
||||
if ($mime_type == egw_vfs::DIR_MIME_TYPE)
|
||||
{
|
||||
$mime_type = 'Directory';
|
||||
}
|
||||
if(!$mime_type)
|
||||
{
|
||||
$mime_type='unknown';
|
||||
}
|
||||
$mime_type= strtolower(str_replace ('/','_',$mime_type));
|
||||
list($mime_part) = explode('_',$mime_type);
|
||||
|
||||
if (!($img=$GLOBALS['egw']->common->image('filemanager',$icon='mime'.$size.'_'.$mime_type)) &&
|
||||
!($img=$GLOBALS['egw']->common->image('filemanager',$icon='mime'.$size.'_'.$mime_part)))
|
||||
{
|
||||
$img = $GLOBALS['egw']->common->image('filemanager',$icon='mime'.$size.'_unknown');
|
||||
}
|
||||
return 'filemanager/'.$icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to fetch the rows for the nextmatch widget
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows
|
||||
* @param array &$readonlys
|
||||
*/
|
||||
function get_rows($query,&$rows,&$readonlys)
|
||||
{
|
||||
$GLOBALS['egw']->session->appsession('index','filemanager',$query);
|
||||
//_debug_array($query);
|
||||
|
||||
if (!egw_vfs::is_dir($query['path']))
|
||||
{
|
||||
$rows = array();
|
||||
$query['total'] = 0;
|
||||
}
|
||||
$dir_is_writable = egw_vfs::is_writable($query['path']);
|
||||
|
||||
$rows = array();
|
||||
foreach(egw_vfs::find($query['path'],array('mindepth'=>1,'maxdepth'=>1)) as $path)
|
||||
{
|
||||
$row = egw_vfs::stat($path);
|
||||
$row['name'] = egw_vfs::basename($path);
|
||||
$row['path'] = $path;
|
||||
$row['mime'] = egw_vfs::mime_content_type($path);
|
||||
$row['icon'] = self::mime_icon($row['mime']);
|
||||
$row['perms'] = egw_vfs::int2mode($row['mode']);
|
||||
// only show link if we have access to the file or dir
|
||||
if (egw_vfs::check_access($row,egw_vfs::READABLE))
|
||||
{
|
||||
if ($row['mime'] == egw_vfs::DIR_MIME_TYPE)
|
||||
{
|
||||
$row['link'] = '/index.php?menuaction=filemanager.filemanager_ui.index&path='.$path;
|
||||
}
|
||||
else
|
||||
{
|
||||
$row['link'] = '/index.php?menuaction=filemanager.uifilemanager.view&path='.base64_encode(dirname($path)).'&file='.base64_encode(egw_vfs::basename($path));
|
||||
// $row['link'] = '/filemanager/webdav.php'.$path;
|
||||
}
|
||||
}
|
||||
$row['user'] = $row['uid'] ? $GLOBALS['egw']->accounts->id2name($row['uid']) : 'root';
|
||||
$row['group'] = $row['gid'] ? $GLOBALS['egw']->accounts->id2name(-$row['gid']) : 'root';
|
||||
$row['hsize'] = egw_vfs::hsize($row['size']);
|
||||
|
||||
//echo $path; _debug_array($row);
|
||||
|
||||
$rows[++$n] = $row;
|
||||
|
||||
if (!$dir_is_writable)
|
||||
{
|
||||
$readonlys["delete[$path]"] = true; // no rights to delete the file
|
||||
}
|
||||
}
|
||||
//_debug_array($readonlys);
|
||||
return count($rows);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* eGroupWare - eTemplates for Application filemanager
|
||||
* http://www.egroupware.org
|
||||
* generated by soetemplate::dump4setup() 2008-01-15 04:17
|
||||
* generated by soetemplate::dump4setup() 2008-03-02 23:05
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package filemanager
|
||||
@ -12,6 +12,10 @@
|
||||
|
||||
$templ_version=1;
|
||||
|
||||
$templ_data[] = array('name' => 'filemanager.index','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:1:{s:1:"A";s:3:"250";}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:10:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"7";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:20:"Go to 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: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:7;a:5:{s:4:"type";s:6:"button";s:4:"name";s:13:"button[paste]";s:4:"size";s:9:"editpaste";s:5:"label";s:5:"Paste";s:4:"help";s:46:"Paste cut or copied files to current directory";}}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:3:{s:4:"type";s:4:"file";s:4:"name";s:6:"upload";s:4:"help";s:42:"Select file to upload in current directory";}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;}}','size' => '','style' => '','modified' => '1204374710',);
|
||||
|
||||
$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:4:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"B";s:3:"30%";s:1:"D";s:3:"120";}i:1;a:9:{s:1:"A";a:4:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Type";s:4:"name";s:4:"type";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:11:"Permissions";s:4:"name";s:4:"mode";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"uid";s:5:"label";s:5:"Owner";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:4:"name";s:3:"gid";s:5:"label";s:5:"Group";}s:1:"H";a:3:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Comment";s:4:"name";s:7:"comment";}s:1:"I";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:9:{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:16:",$row_cont[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:5:"label";s:5:"label";s:16:"$row_cont[perms]";s:4:"span";s:6:",perms";}s:1:"F";a:3:{s:4:"type";s:5:"label";s:4:"name";s:12:"${row}[user]";s:7:"no_lang";s:1:"1";}s:1:"G";a:3:{s:4:"type";s:5:"label";s:4:"name";s:13:"${row}[group]";s:7:"no_lang";s:1:"1";}s:1:"H";a:2:{s:4:"type";s:5:"label";s:4:"name";s:15:"${row}[comment]";}s:1:"I";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:5:{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";}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:9;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.search','template' => '','lang' => '','group' => '0','version' => '1.3.001','data' => 'a:4:{i:0;a:9:{s:4:"type";s:8:"groupbox";s:4:"name";s:10:"debuginfos";s:4:"size";s:1:"4";s:5:"label";s:10:"Debuginfos";s:8:"disabled";s:1:"1";i:1;a:3:{s:4:"type";s:8:"textarea";s:4:"name";s:7:"message";s:8:"readonly";s:1:"1";}i:2;a:1:{s:4:"type";s:5:"label";}i:3;a:1:{s:4:"type";s:5:"label";}i:4;a:1:{s:4:"type";s:5:"label";}}i:1;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:2:{s:1:"C";s:3:"120";s:1:"D";s:3:"120";}i:1;a:5:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:12:"searchstring";s:4:"name";s:17:"searchstringlabel";}s:1:"B";a:3:{s:4:"type";s:4:"text";s:4:"span";s:1:"2";s:4:"name";s:12:"searchstring";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:3:{s:4:"type";s:6:"button";s:5:"label";s:12:"start search";s:4:"name";s:12:"start_search";}s:1:"E";a:1:{s:4:"type";s:5:"label";}}i:2;a:5:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"mime type";}s:1:"B";a:2:{s:4:"type";s:8:"checkbox";s:4:"name";s:8:"checkall";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:3:"All";s:4:"name";s:8:"alllabel";}s:1:"D";a:4:{s:4:"type";s:5:"label";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:8:"checkbox";s:5:"label";s:5:"files";s:4:"name";s:14:"checkonlyfiles";}}}s:4:"rows";i:1;s:4:"cols";i:1;}s:1:"E";a:1:{s:4:"type";s:5:"label";}}i:3;a:5:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:8:"checkbox";s:4:"name";s:14:"checkonlyfiles";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:5:"files";s:4:"name";s:9:"filelabel";}s:1:"D";a:4:{s:4:"type";s:6:"button";s:5:"label";s:12:"clear search";s:4:"name";s:12:"clear_search";s:7:"onclick";s:71:"menuaction=filemanager.uifilemanager.index&action=search&actioncd=clear";}s:1:"E";a:1:{s:4:"type";s:5:"label";}}i:4;a:5:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:8:"checkbox";s:4:"name";s:13:"checkonlydirs";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:9:"directory";s:4:"name";s:8:"dirlabel";}s:1:"D";a:4:{s:4:"type";s:8:"checkbox";s:5:"label";s:5:"Debug";s:4:"name";s:5:"debug";s:8:"disabled";s:1:"1";}s:1:"E";a:1:{s:4:"type";s:5:"label";}}i:5;a:5:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:15:"created between";s:4:"name";s:12:"createdlabel";}s:1:"B";a:2:{s:4:"type";s:8:"checkbox";s:4:"name";s:13:"searchcreated";}s:1:"C";a:3:{s:4:"type";s:4:"date";s:4:"name";s:15:"datecreatedfrom";s:4:"size";s:2:",8";}s:1:"D";a:3:{s:4:"type";s:4:"date";s:4:"name";s:13:"datecreatedto";s:4:"size";s:2:",8";}s:1:"E";a:4:{s:4:"type";s:8:"textarea";s:4:"name";s:17:"searchcreatedtext";s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";}}i:6;a:5:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:16:"modified between";s:4:"name";s:13:"modifiedlabel";}s:1:"B";a:2:{s:4:"type";s:8:"checkbox";s:4:"name";s:14:"searchmodified";}s:1:"C";a:3:{s:4:"type";s:4:"date";s:4:"name";s:16:"datemodifiedfrom";s:4:"size";s:2:",8";}s:1:"D";a:3:{s:4:"type";s:4:"date";s:4:"name";s:14:"datemodifiedto";s:4:"size";s:2:",8";}s:1:"E";a:4:{s:4:"type";s:8:"textarea";s:4:"name";s:18:"searchmodifiedtext";s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";}}}s:4:"rows";i:6;s:4:"cols";i:5;}i:2;a:1:{s:4:"type";s:5:"hrule";}i:3;a:3:{s:4:"type";s:9:"nextmatch";s:4:"size";s:4:"rows";s:4:"name";s:2:"nm";}}','size' => '','style' => '','modified' => '1173101430',);
|
||||
|
||||
$templ_data[] = array('name' => 'filemanager.search.rows','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:2:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";}i:1;a:8:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:2:"Id";s:4:"name";s:11:"vfs_file_id";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:4:"file";s:4:"name";s:7:"fulldir";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:9:"Directory";s:4:"name";s:13:"vfs_directory";}s:1:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"name";s:4:"name";s:8:"vfs_name";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"comment";s:4:"name";s:11:"vfs_comment";}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:9:"mime type";s:4:"name";s:13:"vfs_mime_type";}s:1:"G";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"created";s:4:"name";s:11:"vfs_created";}s:1:"H";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"modified";s:4:"name";s:12:"vfs_modified";}}i:2;a:8:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[vfs_file_id]";s:7:"no_lang";s:1:"1";}s:1:"B";a:3:{s:4:"type";s:4:"html";s:4:"name";s:15:"${row}[fulldir]";s:7:"no_lang";s:1:"1";}s:1:"C";a:3:{s:4:"type";s:4:"html";s:4:"name";s:21:"${row}[vfs_directory]";s:7:"no_lang";s:1:"1";}s:1:"D";a:3:{s:4:"type";s:5:"label";s:4:"name";s:16:"${row}[vfs_name]";s:7:"no_lang";s:1:"1";}s:1:"E";a:3:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[vfs_comment]";s:7:"no_lang";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:5:"label";s:4:"name";s:21:"${row}[vfs_mime_type]";s:7:"no_lang";s:1:"1";}s:1:"G";a:3:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[vfs_created]";s:7:"no_lang";s:1:"1";}s:1:"H";a:3:{s:4:"type";s:5:"label";s:4:"name";s:20:"${row}[vfs_modified]";s:7:"no_lang";s:1:"1";}}}s:4:"rows";i:2;s:4:"cols";i:8;s:4:"size";s:9:"100%,auto";s:7:"options";a:2:{i:0;s:4:"100%";i:1;s:4:"auto";}}}','size' => '100%,auto','style' => '','modified' => '1173104345',);
|
||||
|
@ -1,41 +1,48 @@
|
||||
/*
|
||||
CSS for the filemanager
|
||||
*/
|
||||
|
||||
#fmStatusBar
|
||||
{
|
||||
margin-left:4px;
|
||||
margin-bottom:3px;
|
||||
}
|
||||
|
||||
.fmButton
|
||||
{
|
||||
background-repeat: no-repeat;
|
||||
background-image:url(../default/images/buttonbackground.png);
|
||||
width:28px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
#fmLocation
|
||||
{
|
||||
position:relative;
|
||||
margin-bottom:3px;
|
||||
height:27px;
|
||||
}
|
||||
|
||||
#fmMenu
|
||||
{
|
||||
position:relative;
|
||||
}
|
||||
|
||||
#fmFileWindow
|
||||
{
|
||||
background-color:#ffffff;
|
||||
margin-left:4px;
|
||||
padding:5px;
|
||||
position:relative;
|
||||
border-right: #cccccc 1px solid;
|
||||
border-top: #9c9c9c 2px solid;
|
||||
border-left: #9c9c9c 2px solid;
|
||||
border-bottom: #cccccc 1px solid
|
||||
}
|
||||
/**
|
||||
* CSS for new eTemplate filemanager UI
|
||||
*/
|
||||
|
||||
.perms { font-family: monospace; font-weight: bold; }
|
||||
.address input { font-size: 140%; font-weight: bold; }
|
||||
|
||||
/*
|
||||
CSS for the filemanager
|
||||
*/
|
||||
|
||||
#fmStatusBar
|
||||
{
|
||||
margin-left:4px;
|
||||
margin-bottom:3px;
|
||||
}
|
||||
|
||||
.fmButton
|
||||
{
|
||||
background-repeat: no-repeat;
|
||||
background-image:url(../default/images/buttonbackground.png);
|
||||
width:28px;
|
||||
height:28px;
|
||||
}
|
||||
|
||||
#fmLocation
|
||||
{
|
||||
position:relative;
|
||||
margin-bottom:3px;
|
||||
height:27px;
|
||||
}
|
||||
|
||||
#fmMenu
|
||||
{
|
||||
position:relative;
|
||||
}
|
||||
|
||||
#fmFileWindow
|
||||
{
|
||||
background-color:#ffffff;
|
||||
margin-left:4px;
|
||||
padding:5px;
|
||||
position:relative;
|
||||
border-right: #cccccc 1px solid;
|
||||
border-top: #9c9c9c 2px solid;
|
||||
border-left: #9c9c9c 2px solid;
|
||||
border-bottom: #cccccc 1px solid
|
||||
}
|
||||
|
90
filemanager/templates/default/index.xet
Normal file
90
filemanager/templates/default/index.xet
Normal file
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="filemanager.index.rows" template="" lang="" group="0" version="1.5.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
<column width="30%"/>
|
||||
<column/>
|
||||
<column width="120"/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<nextmatch-sortheader label="Type" id="type" align="center"/>
|
||||
<nextmatch-sortheader label="Name" id="name"/>
|
||||
<nextmatch-sortheader label="Size" id="size"/>
|
||||
<nextmatch-sortheader label="Modified" id="mtime"/>
|
||||
<nextmatch-sortheader label="Permissions" id="mode"/>
|
||||
<nextmatch-sortheader id="uid" label="Owner"/>
|
||||
<nextmatch-sortheader id="gid" label="Group"/>
|
||||
<nextmatch-header label="Comment" id="comment"/>
|
||||
<hbox options="0,0">
|
||||
<description value="Actions"/>
|
||||
<button image="check" label="Check all" id="check_all" statustext="Check all" onclick="toggle_all(this.form,form::name('checked[]')); return false;" needed="1" align="right"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row class="row">
|
||||
<image label="$row_cont[mime]" src="${row}[icon]" align="center"/>
|
||||
<description options=",$row_cont[link]" id="${row}[name]" no_lang="1"/>
|
||||
<description id="${row}[hsize]" align="right"/>
|
||||
<date-time id="${row}[mtime]" readonly="true"/>
|
||||
<description value="$row_cont[perms]" class="perms"/>
|
||||
<description id="${row}[user]" no_lang="1"/>
|
||||
<description id="${row}[group]" no_lang="1"/>
|
||||
<description id="${row}[comment]"/>
|
||||
<hbox align="right">
|
||||
<button image="edit" label="Edit settings" id="edit[$row_cont[path]]" statustext="Rename, change permissions or ownership"/>
|
||||
<button id="delete[$row_cont[path]]" image="delete" label="Delete" statustext="Delete this file or directory" onclick="return confirm('Delete this file or directory');" align="center"/>
|
||||
<checkbox id="checked[]" align="right" options="$row_cont[path]"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="filemanager.index" template="" lang="" group="0" version="1.5.001">
|
||||
<grid>
|
||||
<columns>
|
||||
<column width="250"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description span="all" class="redItalic" id="nm[msg]"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<hbox span="all">
|
||||
<button image="goup" label="Up" id="button[up]"/>
|
||||
<button id="button[home]" image="gohome" label="Go to home directory"/>
|
||||
<textbox id="nm[path]" size="80" label="Path" onchange="1" class="address"/>
|
||||
<button id="button[go]" image="key_enter" label="Go to"/>
|
||||
<image src="buttonseparator"/>
|
||||
<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 id="button[paste]" image="editpaste" label="Paste" statustext="Paste cut or copied files to current directory"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch options="filemanager.index.rows" span="all" id="nm"/>
|
||||
</row>
|
||||
<row>
|
||||
<hbox>
|
||||
<file id="upload" statustext="Select file to upload in current directory"/>
|
||||
<button label="Upload" id="button[upload]"/>
|
||||
</hbox>
|
||||
<hbox align="right">
|
||||
<menulist>
|
||||
<menupopup id="action" options="Select action..." onchange="1"/>
|
||||
</menulist>
|
||||
<button image="arrow_ltr" label="Check all" id="check_all" statustext="Check all" onclick="toggle_all(this.form,form::name('nm[rows][checked][]')); return false;" needed="1" class="checkAllArrow"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
@ -59,6 +59,7 @@
|
||||
*/
|
||||
class egw_vfs extends vfs_stream_wrapper
|
||||
{
|
||||
const PREFIX = 'vfs://default';
|
||||
/**
|
||||
* Readable bit, for dirs traversable
|
||||
*/
|
||||
@ -97,7 +98,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
{
|
||||
throw new egw_exception_assertion_failed("Filename '$path' is not an absolute path!");
|
||||
}
|
||||
return fopen(self::SCHEME.'://default'.$path);
|
||||
return fopen(self::SCHEME.'://default'.$path,$mode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,7 +130,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
if (($from_fp = self::fopen($from,'r')) &&
|
||||
($to_fp = self::fopen($to,'w')))
|
||||
{
|
||||
$ret = stream_copy_to_stream($from,$to) !== false;
|
||||
$ret = stream_copy_to_stream($from_fp,$to_fp) !== false;
|
||||
}
|
||||
if ($from_fp)
|
||||
{
|
||||
@ -154,7 +155,22 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
{
|
||||
throw new egw_exception_assertion_failed("File '$path' is not an absolute path!");
|
||||
}
|
||||
return self::url_stat($path,0);
|
||||
if (($stat = self::url_stat($path,0)))
|
||||
{
|
||||
$stat = array_slice($stat,13); // remove numerical indices 0-12
|
||||
}
|
||||
return $stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_dir() version working only inside the vfs
|
||||
*
|
||||
* @param string $path
|
||||
* @return boolean
|
||||
*/
|
||||
static function is_dir($path)
|
||||
{
|
||||
return $path[0] == '/' && is_dir(self::SCHEME.'://default'.$path);
|
||||
}
|
||||
|
||||
|
||||
@ -224,7 +240,8 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
* @param string/array $base base of the search
|
||||
* @param array $options=null the following keys are allowed:
|
||||
* - type => {d|f} d=dirs, f=files, default both
|
||||
* - dirs_last => {true|false(default)} put the dirs behind the files they contain
|
||||
* - depth => {true|false(default)} put the contents of a dir before the dir itself
|
||||
* - mindepth,maxdepth minimal or maximal depth to be returned
|
||||
* - name,path => pattern with *,? wildcards, eg. "*.php"
|
||||
* - name_preg,path_preg => preg regular expresion, eg. "/(vfs|wrapper)/"
|
||||
* - uid,user,gid,group,nouser,nogroup file belongs to user/group with given name or (numerical) id
|
||||
@ -232,18 +249,20 @@ 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!)
|
||||
* @param string/array/true $exec=null function to call with each found file or dir as first 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!
|
||||
* @return array of pathes if no $exec, otherwise path => stat pairs
|
||||
*/
|
||||
function find($base,$options=null,$exec=null,$exec_params=null)
|
||||
static function find($base,$options=null,$exec=null,$exec_params=null)
|
||||
{
|
||||
//error_log(__METHOD__."(".print_r($base,true).",".print_r($options,true).",".print_r($exec,true).",".print_r($exec_params,true).")\n");
|
||||
|
||||
$type = $options['type']; // 'd' or 'f'
|
||||
$dirs_last = $options['dirs_last']; // list dirs after the files they contain
|
||||
|
||||
$dirs_last = $options['depth']; // put content of dirs before the dir itself
|
||||
|
||||
// process some of the options (need to be done only once)
|
||||
if (isset($options['name']) && !isset($options['name_preg'])) // change from simple *,? wildcards to preg regular expression once
|
||||
{
|
||||
@ -275,6 +294,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
$options['gid'] = 0;
|
||||
}
|
||||
}
|
||||
$url = $options['url'];
|
||||
|
||||
if (!is_array($base))
|
||||
{
|
||||
@ -295,23 +315,30 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
$result = array();
|
||||
foreach($base as $path)
|
||||
{
|
||||
if (!$url) $path = egw_vfs::PREFIX . $path;
|
||||
|
||||
$is_dir = is_dir($path);
|
||||
|
||||
if (!$dirs_last || !$is_dir)
|
||||
if ((int)$options['mindepth'] == 0 && (!$dirs_last || !$is_dir))
|
||||
{
|
||||
self::_check_add($options,$path,$result);
|
||||
}
|
||||
if ($is_dir && ($dir = opendir($path)))
|
||||
if ($is_dir && (!isset($options['maxdepth']) || $options['maxdepth'] > 0) && ($dir = @opendir($path)))
|
||||
{
|
||||
while($file = readdir($dir))
|
||||
{
|
||||
$file = $path.'/'.$file;
|
||||
|
||||
self::_check_add($options,$file,$result);
|
||||
|
||||
if (is_dir($file))
|
||||
if ((int)$options['mindepth'] <= 1)
|
||||
{
|
||||
foreach(self::find($file,$options,true) as $p => $s)
|
||||
self::_check_add($options,$file,$result,1);
|
||||
}
|
||||
if (is_dir($file) && (!isset($options['maxdepth']) || $options['maxdepth'] > 1))
|
||||
{
|
||||
$opts = $options;
|
||||
if ($opts['mindepth']) $opts['mindepth']--;
|
||||
if ($opts['maxdepth']) $opts['maxdepth']++;
|
||||
foreach(self::find($options['url']?$file:parse_url($file,PHP_URL_PATH),$opts,true) as $p => $s)
|
||||
{
|
||||
unset($result[$p]);
|
||||
$result[$p] = $s;
|
||||
@ -319,14 +346,13 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
|
||||
if ($dirs_last)
|
||||
{
|
||||
self::_check_add($options,$path,$result);
|
||||
}
|
||||
}
|
||||
if ($is_dir && (int)$options['mindepth'] == 0 && $dirs_last)
|
||||
{
|
||||
self::_check_add($options,$path,$result);
|
||||
}
|
||||
}
|
||||
//_debug_array($result);
|
||||
//echo $path; _debug_array($result);
|
||||
if ($exec !== true && is_callable($exec))
|
||||
{
|
||||
if (!is_array($exec_params))
|
||||
@ -342,6 +368,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
//echo "egw_vfs::find($path)="; _debug_array(array_keys($result));
|
||||
if ($exec !== true)
|
||||
{
|
||||
return array_keys($result);
|
||||
@ -356,7 +383,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
* @param string $path name of path to add
|
||||
* @param array &$result here we add the stat for the key $path, if the checks are successful
|
||||
*/
|
||||
private function _check_add($options,$path,&$result)
|
||||
private static function _check_add($options,$path,&$result)
|
||||
{
|
||||
$type = $options['type']; // 'd' or 'f'
|
||||
|
||||
@ -368,7 +395,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
{
|
||||
return; // not found, should not happen
|
||||
}
|
||||
if (isset($options['name_preg']) && !preg_match($options['name_preg'],basename($path)) ||
|
||||
if (isset($options['name_preg']) && !preg_match($options['name_preg'],self::basename($path)) ||
|
||||
isset($options['path_preg']) && !preg_match($options['path_preg'],$path))
|
||||
{
|
||||
return; // wrong name or path
|
||||
@ -399,10 +426,15 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
{
|
||||
return; // not create/modified in the spezified time
|
||||
}
|
||||
// do we return url or just vfs pathes
|
||||
if (!$options['url'])
|
||||
{
|
||||
$path = parse_url($path,PHP_URL_PATH);
|
||||
}
|
||||
$result[$path] = $stat;
|
||||
}
|
||||
|
||||
private function _check_num($value,$argument)
|
||||
private static function _check_num($value,$argument)
|
||||
{
|
||||
if (is_int($argument) && $argument >= 0 || $argument[0] != '-' && $argument[0] != '+')
|
||||
{
|
||||
@ -417,7 +449,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
//echo "_check_num($value,$argument) check > == ".(int)($value > (int)substr($argument,1))."\n";
|
||||
return $value > (int) substr($argument,1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursiv remove all given url's, including it's content if they are files
|
||||
*
|
||||
@ -426,7 +458,7 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
*/
|
||||
static function remove($urls)
|
||||
{
|
||||
return self::find($urls,array('dirs_last'=>true),array(__CLASS__,'_rm_rmdir'));
|
||||
return self::find($urls,array('depth'=>true),array(__CLASS__,'_rm_rmdir'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -671,6 +703,32 @@ class egw_vfs extends vfs_stream_wrapper
|
||||
|
||||
return $sP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable size values in k or M
|
||||
*
|
||||
* @param int $size
|
||||
* @return string
|
||||
*/
|
||||
static function hsize($size)
|
||||
{
|
||||
if ($size < 1024) return $size;
|
||||
if ($size < 1024*1024) return sprintf('%3.1lfk',(float)$size/1024);
|
||||
return sprintf('%3.1lfM',(float)$size/(1024*1024));
|
||||
}
|
||||
|
||||
/**
|
||||
* like basename($path), but also working if the 1. char of the basename is non-ascii
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
static function basename($path)
|
||||
{
|
||||
$parts = explode('/',$path);
|
||||
|
||||
return array_pop($parts);
|
||||
}
|
||||
}
|
||||
|
||||
egw_vfs::$user = (int) $GLOBALS['egw_info']['user']['account_id'];
|
||||
|
@ -177,14 +177,14 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
// new file --> create it in the DB
|
||||
if ($this->operation == self::STORE2FS)
|
||||
{
|
||||
$stmt = self::$pdo->prepare('INSERT INTO '.self::TABLE.' (fs_name,fs_dir,fs_mode,fs_uid,fs_gid,fs_created,fs_modified,fs_creator'.
|
||||
$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'.
|
||||
') VALUES (:fs_name,:fs_dir,:fs_mode,:fs_uid,:fs_gid,:fs_created,:fs_modified,:fs_creator)');
|
||||
}
|
||||
else
|
||||
{
|
||||
$stmt = self::$pdo->prepare('INSERT INTO '.self::TABLE.' (fs_name,fs_dir,fs_mode,fs_uid,fs_gid,fs_created,fs_modified,fs_creator,fs_content'.
|
||||
$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_content'.
|
||||
') VALUES (:fs_name,:fs_dir,:fs_mode,:fs_uid,:fs_gid,:fs_created,:fs_modified,:fs_creator,:fs_content)');
|
||||
$stmt->bindParam(':fs_content',$this->open_stream,PDO::PARAM_LOB);
|
||||
$stmt->bindParam(':fs_content',$this->opened_stream,PDO::PARAM_LOB);
|
||||
}
|
||||
$values = array(
|
||||
'fs_name' => basename($path),
|
||||
@ -203,8 +203,12 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
{
|
||||
$stmt->bindParam(':'.$name,$val);
|
||||
}
|
||||
$stmt->execute();
|
||||
$this->opened_fs_id = self::$pdo->lastInsertId('fs_id');
|
||||
if (!$stmt->execute() || !($this->opened_fs_id = self::$pdo->lastInsertId('fs_id')))
|
||||
{
|
||||
$this->opened_stream = $this->opened_path = $this->opened_mode = null;
|
||||
echo self::$pdo->errorInfo()."\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -242,7 +246,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
{
|
||||
if (self::LOG_LEVEL > 1) error_log(__METHOD__."()");
|
||||
|
||||
if (is_null($this->opened_path) || !is_resource($this->opened_stream))
|
||||
if (is_null($this->opened_path) || !is_resource($this->opened_stream) || !$this->opened_fs_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -813,13 +817,15 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
$this->opened_dir = null;
|
||||
return false;
|
||||
}
|
||||
self::$stat_cache = $this->opened_dir = array();
|
||||
$this->opened_dir = array();
|
||||
$query = 'SELECT fs_id,fs_name,fs_mode,fs_uid,fs_gid,fs_size,fs_mime,fs_created,fs_modified FROM '.self::TABLE.' WHERE fs_dir=?';
|
||||
// only return readable files, if dir is not writable by user
|
||||
if (!egw_vfs::check_access($stat,egw_vfs::WRITABLE))
|
||||
{
|
||||
$query .= ' AND '.self::_sql_readable();
|
||||
}
|
||||
$query = "/* sqlfs::dir_opendir($path) */ ".$query;
|
||||
|
||||
$stmt = self::$pdo->prepare($query);
|
||||
$stmt->setFetchMode(PDO::FETCH_ASSOC);
|
||||
if ($stmt->execute(array($stat['ino'])))
|
||||
@ -906,6 +912,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
$query = str_replace('fs_name=?','fs_name='.self::$pdo->quote($name),$base_query).'('.$query.')';
|
||||
}
|
||||
}
|
||||
$query = "/* sqlfs::url_stat($path) */ ".$query;
|
||||
//echo "query=$query\n";
|
||||
|
||||
if (!($result = self::$pdo->query($query)) || !($info = $result->fetch(PDO::FETCH_ASSOC)))
|
||||
@ -954,8 +961,8 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
if (!is_array($this->opened_dir)) return false;
|
||||
|
||||
$file = current($this->opened_dir); next($this->opened_dir);
|
||||
|
||||
return $file ? $file : false;
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1036,7 +1043,24 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
|
||||
$dsn = $server['db_type'].':host='.$server['db_host'].';dbname='.$server['db_name'];
|
||||
break;
|
||||
}
|
||||
return self::$pdo = new PDO($dsn,$server['db_user'],$server['db_pass']);
|
||||
self::$pdo = new PDO($dsn,$server['db_user'],$server['db_pass']);
|
||||
|
||||
// set client charset of the connection
|
||||
$charset = $GLOBALS['egw']->translation->charset();
|
||||
switch($server['db_type'])
|
||||
{
|
||||
case 'mysql':
|
||||
if (isset($GLOBALS['egw']->db->Link_ID->charset2mysql[$charset])) $charset = $GLOBALS['egw']->db->Link_ID->charset2mysql[$charset];
|
||||
// fall throught
|
||||
case 'pgsql':
|
||||
$query = "SET NAMES '$charset'";
|
||||
break;
|
||||
}
|
||||
if ($query)
|
||||
{
|
||||
self::$pdo->exec($query);
|
||||
}
|
||||
return self::$pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -504,7 +504,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
|
||||
static $mime_magic;
|
||||
if (is_null($mime_magic))
|
||||
{
|
||||
$mime_magic = mime_magic();
|
||||
$mime_magic = new mime_magic();
|
||||
}
|
||||
$mime = $mime_magic->filename2mime(parse_url($url,PHP_URL_PATH));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user