first work on UI for a new filemanager and some vfs bugfixes and improvments

This commit is contained in:
Ralf Becker 2008-03-02 21:44:15 +00:00
parent 9887c58b4d
commit 4df4fd9f06
9 changed files with 652 additions and 84 deletions

View File

@ -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";

View File

@ -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);
}

View 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);
}
}

View File

@ -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',);

View File

@ -1,3 +1,10 @@
/**
* 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
*/

View 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>

View File

@ -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,17 +249,19 @@ 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] != '+')
{
@ -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'];

View File

@ -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)))
@ -955,7 +962,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
$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;
}
/**

View File

@ -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));
}