2008-03-02 22:44:15 +01:00
< ? php
/**
2008-04-14 07:54:10 +02:00
* eGroupWare - Filemanager - user interface
2008-03-02 22:44:15 +01:00
*
* @ link http :// www . egroupware . org
2008-03-03 08:53:43 +01:00
* @ package filemanager
2008-03-02 22:44:15 +01:00
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
2010-04-22 19:38:01 +02:00
* @ copyright ( c ) 2008 - 10 by Ralf Becker < RalfBecker - AT - outdoor - training . de >
2008-03-02 22:44:15 +01:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2008-03-18 10:07:06 +01:00
2009-12-01 15:51:13 +01:00
/**
* Filemanage user interface class
*/
2008-03-02 22:44:15 +01:00
class filemanager_ui
{
/**
* Methods callable via menuaction
*
* @ var array
*/
var $public_functions = array (
'index' => true ,
2008-03-03 23:15:44 +01:00
'file' => true ,
2008-03-02 22:44:15 +01:00
);
2010-12-28 04:12:57 +01:00
2010-10-15 21:42:38 +02:00
/**
* Views available from plugins
2010-12-28 04:12:57 +01:00
*
2010-10-15 21:42:38 +02:00
* @ var array
*/
public static $views = array (
'filemanager_ui::listview' => 'Listview' ,
);
public static $views_init = false ;
2008-04-16 09:07:31 +02:00
2008-10-05 19:07:36 +02:00
/**
* Constructor
*
*/
function __construct ()
{
// strip slashes from _GET parameters, if someone still has magic_quotes_gpc on
if ( get_magic_quotes_gpc () && $_GET )
{
$_GET = etemplate :: array_stripslashes ( $_GET );
}
2008-11-09 17:33:09 +01:00
// do we have root rights
if ( egw_session :: appsession ( 'is_root' , 'filemanager' ))
{
egw_vfs :: $is_root = true ;
}
2010-12-28 04:12:57 +01:00
2010-10-15 21:42:38 +02:00
self :: init_views ();
}
2010-12-28 04:12:57 +01:00
2010-10-15 21:42:38 +02:00
/**
* Initialise and return available views
2010-12-28 04:12:57 +01:00
*
2010-10-15 21:42:38 +02:00
* @ return array with method => label pairs
*/
public static function init_views ()
{
if ( ! self :: $views_init )
{
// translate our labels
foreach ( self :: $views as $method => & $label )
{
$label = lang ( $label );
}
// search for plugins with additional filemanager views
foreach ( $GLOBALS [ 'egw' ] -> hooks -> process ( 'filemanager_views' ) as $app => $views )
{
if ( $views ) self :: $views += $views ;
}
self :: $views_init = true ;
}
return self :: $views ;
2008-11-09 17:33:09 +01:00
}
/**
2010-10-15 21:42:38 +02:00
* Get active view
2008-11-09 17:33:09 +01:00
*
2010-10-15 21:42:38 +02:00
* @ return string
2008-11-09 17:33:09 +01:00
*/
2010-10-16 14:26:54 +02:00
public function get_view ()
2008-11-09 17:33:09 +01:00
{
2010-10-15 21:42:38 +02:00
$view =& egw_cache :: getSession ( 'filemanager' , 'view' );
if ( isset ( $_GET [ 'view' ]))
2008-11-09 17:33:09 +01:00
{
2010-10-15 21:42:38 +02:00
$view = $_GET [ 'view' ];
2008-11-09 17:33:09 +01:00
}
2010-10-15 21:42:38 +02:00
if ( ! isset ( self :: $views [ $view ]))
2008-11-09 17:33:09 +01:00
{
2010-10-16 14:26:54 +02:00
reset ( self :: $views );
2010-10-15 21:42:38 +02:00
$view = key ( self :: $views );
2008-11-09 17:33:09 +01:00
}
2010-10-15 21:42:38 +02:00
return $view ;
2008-10-05 19:07:36 +02:00
}
2008-03-02 22:44:15 +01:00
/**
* Main filemanager page
*
* @ param array $content = null
* @ param string $msg = null
*/
2008-03-03 23:15:44 +01:00
function index ( array $content = null , $msg = null )
2008-03-02 22:44:15 +01:00
{
if ( ! is_array ( $content ))
{
$content = array (
2009-12-01 15:51:13 +01:00
'nm' => egw_session :: appsession ( 'index' , 'filemanager' ),
2008-03-02 22:44:15 +01:00
);
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'
2008-03-03 13:16:11 +01:00
'filter' => '1' , // current dir only
2008-03-02 22:44:15 +01:00
'no_filter2' => True , // I disable the 2. filter (params are the same as for filter)
'no_cat' => True , // I disable the cat-selectbox
2008-03-03 13:16:11 +01:00
'lettersearch' => True , // I show a lettersearch
2008-03-02 22:44:15 +01:00
'searchletter' => false , // I0 active letter of the lettersearch or false for [all]
2008-09-04 08:44:48 +02:00
'start' => 0 , // IO position in list
2008-03-02 22:44:15 +01:00
'order' => 'name' , // IO name of the column to sort after (optional for the sortheaders)
'sort' => 'ASC' , // IO direction of the sort: 'ASC' or 'DESC'
2008-03-03 08:53:43 +01:00
'default_cols' => '!comment,ctime' , // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
2008-04-16 09:07:31 +02:00
'csv_fields' => false , // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
2008-03-02 22:44:15 +01:00
//or array with name=>label or name=>array('label'=>label,'type'=>type) pairs (type is a eT widget-type)
);
2008-10-14 15:20:31 +02:00
$content [ 'nm' ][ 'path' ] = self :: get_home_dir ();
2008-03-02 22:44:15 +01:00
}
2008-08-28 13:09:09 +02:00
if ( isset ( $_GET [ 'msg' ])) $msg = $_GET [ 'msg' ];
2009-05-06 17:15:39 +02:00
// switch to projectmanager folders
if ( isset ( $_GET [ 'pm_id' ]))
{
$_GET [ 'path' ] = '/apps/projectmanager' . (( int ) $_GET [ 'pm_id' ] ? '/' . ( int ) $_GET [ 'pm_id' ] : '' );
}
2008-09-04 08:44:48 +02:00
if ( isset ( $_GET [ 'path' ]) && ( $path = $_GET [ 'path' ]))
2008-08-27 13:17:00 +02:00
{
2009-04-30 10:09:50 +02:00
switch ( $path )
{
case '..' :
$path = egw_vfs :: dirname ( $content [ 'nm' ][ 'path' ]);
break ;
case '~' :
$path = self :: get_home_dir ();
break ;
}
2009-04-06 15:46:45 +02:00
if ( $path [ 0 ] == '/' && egw_vfs :: stat ( $path , true ) && egw_vfs :: is_dir ( $path ) && egw_vfs :: check_access ( $path , egw_vfs :: READABLE ))
2008-09-04 08:44:48 +02:00
{
$content [ 'nm' ][ 'path' ] = $path ;
2008-10-05 19:07:36 +02:00
}
2008-09-04 08:44:48 +02:00
else
2008-08-27 13:17:00 +02:00
{
2010-05-11 17:02:30 +02:00
$msg .= lang ( 'The requested path %1 is not available.' , urldecode ( $path ));
2008-08-27 13:17:00 +02:00
}
2009-04-23 08:05:48 +02:00
// reset lettersearch as it confuses users (they think the dir is empty)
$content [ 'nm' ][ 'searchletter' ] = false ;
// switch recusive display off
if ( ! $content [ 'nm' ][ 'filter' ]) $content [ 'nm' ][ 'filter' ] = '1' ;
2008-03-02 22:44:15 +01:00
}
}
2010-10-15 21:42:38 +02:00
$view = self :: get_view ();
2010-10-15 22:08:54 +02:00
if ( strpos ( $view , '::' ) !== false && version_compare ( PHP_VERSION , '5.3.0' , '<' ))
{
$view = explode ( '::' , $view );
}
2010-10-15 21:42:38 +02:00
call_user_func ( $view , $content , $msg );
}
/**
* Make the current user ( vfs ) root
*
* The user / pw is either the setup config user or a specially configured vfs_root user
*
* @ param string $user = '' setup config user to become root or '' to log off as root
* @ param string $password = null setup config password to become root
* @ param boolean & $is_setup = null on return true if authenticated user is setup config user , false otherwise
* @ return boolean true is root user given , false otherwise ( including logout / empty $user )
*/
protected function sudo ( $user = '' , $password = null , & $is_setup = null )
{
if ( ! $user )
{
$is_root = $is_setup = false ;
}
else
{
// config user & password
$is_setup = egw_session :: user_pw_hash ( $user , $password ) === $GLOBALS [ 'egw_info' ][ 'server' ][ 'config_hash' ];
// or vfs root user from setup >> configuration
$is_root = $is_setup || $GLOBALS [ 'egw_info' ][ 'server' ][ 'vfs_root_user' ] &&
in_array ( $user , preg_split ( '/, */' , $GLOBALS [ 'egw_info' ][ 'server' ][ 'vfs_root_user' ])) &&
$GLOBALS [ 'egw' ] -> auth -> authenticate ( $user , $password , 'text' );
}
//echo "<p>".__METHOD__."('$user','$password',$is_setup) user_pw_hash(...)='".egw_session::user_pw_hash($user,$password)."', config_hash='{$GLOBALS['egw_info']['server']['config_hash']}' --> returning ".array2string($is_root)."</p>\n";
egw_session :: appsession ( 'is_setup' , 'filemanager' , $is_setup );
return egw_session :: appsession ( 'is_root' , 'filemanager' , egw_vfs :: $is_root = $is_root );
}
/**
* Filemanager listview
*
* @ param array $content = null
* @ param string $msg = null
*/
function listview ( array $content = null , $msg = null )
{
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'include_xajax' ] = true ;
$tpl = new etemplate ( 'filemanager.index' );
2008-03-02 22:44:15 +01:00
$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' ]);
}
2009-12-01 15:51:13 +01:00
$clipboard_files = egw_session :: appsession ( 'clipboard_files' , 'filemanager' );
$clipboard_type = egw_session :: appsession ( 'clipboard_type' , 'filemanager' );
2008-03-02 22:44:15 +01:00
2010-05-11 17:02:30 +02:00
// be tolerant with (in previous versions) not correct urlencoded pathes
2010-05-12 14:54:41 +02:00
if ( $content [ 'nm' ][ 'path' ][ 0 ] == '/' && ! egw_vfs :: stat ( $content [ 'nm' ][ 'path' ], true ) && egw_vfs :: stat ( urldecode ( $content [ 'nm' ][ 'path' ])))
2010-05-11 17:02:30 +02:00
{
$content [ 'nm' ][ 'path' ] = urldecode ( $content [ 'nm' ][ 'path' ]);
}
2008-03-02 22:44:15 +01:00
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' ]);
2009-04-09 16:05:14 +02:00
// switch recusive display off
if ( ! $content [ 'nm' ][ 'filter' ]) $content [ 'nm' ][ 'filter' ] = '1' ;
2008-03-02 22:44:15 +01:00
}
break ;
case 'home' :
2008-10-14 15:20:31 +02:00
$content [ 'nm' ][ 'path' ] = self :: get_home_dir ();
2008-03-02 22:44:15 +01:00
break ;
case 'createdir' :
if ( $content [ 'nm' ][ 'path' ][ 0 ] != '/' )
{
2009-12-01 15:51:13 +01:00
$ses = egw_session :: appsession ( 'index' , 'filemanager' );
2008-03-02 22:44:15 +01:00
$old_path = $ses [ 'path' ];
2010-05-12 14:54:41 +02:00
$content [ 'nm' ][ 'path' ] = egw_vfs :: concat ( $old_path , $content [ 'nm' ][ 'path' ]);
2008-03-02 22:44:15 +01:00
}
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 )
{
2009-12-01 15:51:13 +01:00
$ses = egw_session :: appsession ( 'index' , 'filemanager' );
2008-03-02 22:44:15 +01:00
$old_path = $ses [ 'path' ];
}
$content [ 'nm' ][ 'path' ] = $old_path ;
}
break ;
2009-03-19 21:12:35 +01:00
case 'symlink' :
$target = $content [ 'nm' ][ 'path' ];
2009-12-01 15:51:13 +01:00
$ses = egw_session :: appsession ( 'index' , 'filemanager' );
2009-03-19 21:12:35 +01:00
$content [ 'nm' ][ 'path' ] = $ses [ 'path' ];
2009-04-09 16:05:14 +02:00
$link = egw_vfs :: concat ( $content [ 'nm' ][ 'path' ], egw_vfs :: basename ( $target ));
2009-03-19 21:12:35 +01:00
$abs_target = $target [ 0 ] == '/' ? $target : egw_vfs :: concat ( $content [ 'nm' ][ 'path' ], $target );
if ( ! egw_vfs :: stat ( $abs_target ))
{
2010-05-11 17:02:30 +02:00
$content [ 'nm' ][ 'msg' ] = lang ( 'Link target %1 not found!' , urldecode ( $abs_target ));
2009-03-19 21:12:35 +01:00
break ;
}
$content [ 'nm' ][ 'msg' ] = egw_vfs :: symlink ( $target , $link ) ?
2010-05-11 17:02:30 +02:00
lang ( 'Symlink to %1 created.' , $target ) : lang ( 'Error creating symlink to target %1!' , urldecode ( $target ));
2009-03-19 21:12:35 +01:00
break ;
2008-03-02 22:44:15 +01:00
case 'paste' :
$content [ 'nm' ][ 'msg' ] = self :: action ( $clipboard_type . '_paste' , $clipboard_files , $content [ 'nm' ][ 'path' ]);
break ;
2009-04-09 16:05:14 +02:00
case 'linkpaste' :
$content [ 'nm' ][ 'msg' ] = self :: action ( 'link_paste' , $clipboard_files , $content [ 'nm' ][ 'path' ]);
break ;
2008-03-02 22:44:15 +01:00
case 'upload' :
2009-02-26 15:48:53 +01:00
if ( ! $content [ 'upload' ])
{
$content [ 'nm' ][ 'msg' ] = lang ( 'You need to select some files first!' );
break ;
}
$upload_success = $upload_failure = array ();
foreach ( isset ( $content [ 'upload' ][ 0 ]) ? $content [ 'upload' ] : array ( $content [ 'upload' ]) as $upload )
2008-03-02 22:44:15 +01:00
{
2010-05-11 17:02:30 +02:00
// encode chars which special meaning in url/vfs (some like / get removed!)
$to = egw_vfs :: concat ( $content [ 'nm' ][ 'path' ], egw_vfs :: encodePathComponent ( $upload [ 'name' ]));
2009-02-26 15:48:53 +01:00
if ( $upload && is_uploaded_file ( $upload [ 'tmp_name' ]) &&
( egw_vfs :: is_writable ( $content [ 'nm' ][ 'path' ]) || egw_vfs :: is_writable ( $to )) &&
copy ( $upload [ 'tmp_name' ], egw_vfs :: PREFIX . $to ))
{
$upload_success [] = $upload [ 'name' ];
}
else
{
$upload_failure [] = $upload [ 'name' ];
}
2008-03-02 22:44:15 +01:00
}
2009-02-26 15:48:53 +01:00
$content [ 'nm' ][ 'msg' ] = '' ;
if ( $upload_success )
2008-03-02 22:44:15 +01:00
{
2009-02-26 15:48:53 +01:00
$content [ 'nm' ][ 'msg' ] = count ( $upload_success ) == 1 && ! $upload_failure ? lang ( 'File successful uploaded.' ) :
2010-05-11 17:02:30 +02:00
lang ( '%1 successful uploaded.' , urldecode ( implode ( ', ' , $upload_success )));
2009-02-26 15:48:53 +01:00
}
if ( $upload_failure )
{
2010-02-05 03:54:47 +01:00
$content [ 'nm' ][ 'msg' ] .= ( $upload_success ? " \n " : '' ) . lang ( 'Error uploading file!' ) . " \n " . etemplate :: max_upload_size_message ();
2008-03-02 22:44:15 +01:00
}
break ;
}
}
2009-04-06 15:46:45 +02:00
if ( ! egw_vfs :: stat ( $content [ 'nm' ][ 'path' ], true ) || ! egw_vfs :: is_dir ( $content [ 'nm' ][ 'path' ]))
2008-03-02 22:44:15 +01:00
{
2008-08-28 13:09:09 +02:00
$content [ 'nm' ][ 'msg' ] .= ' ' . lang ( 'Directory not found or no permission to access it!' );
2008-03-02 22:44:15 +01:00
}
else
{
$dir_is_writable = egw_vfs :: is_writable ( $content [ 'nm' ][ 'path' ]);
}
2008-03-04 08:35:05 +01:00
$content [ 'paste_tooltip' ] = $clipboard_files ? '<p><b>' . lang ( '%1 the following files into current directory' ,
2010-05-11 17:02:30 +02:00
$clipboard_type == 'copy' ? lang ( 'Copy' ) : lang ( 'Move' )) . ':</b><br />' . urldecode ( implode ( '<br />' , $clipboard_files )) . '</p>' : '' ;
2009-04-09 16:05:14 +02:00
$content [ 'linkpaste_tooltip' ] = $clipboard_files ? '<p><b>' . lang ( '%1 the following files into current directory' ,
2010-05-11 17:02:30 +02:00
lang ( 'link' )) . ':</b><br />' . urldecode ( implode ( '<br />' , $clipboard_files )) . '</p>' : '' ;
2010-05-06 08:53:52 +02:00
$content [ 'mailpaste_tooltip' ] = $clipboard_files ? '<p><b>' . lang ( 'Mail files' ) .
2010-05-11 17:02:30 +02:00
':</b><br />' . urldecode ( implode ( '<br />' , $clipboard_files )) . '</p>' : '' ;
2010-05-09 16:08:36 +02:00
$content [ 'mailpaste_files' ] = $clipboard_files ;
2010-02-05 03:54:47 +01:00
$content [ 'upload_size' ] = etemplate :: max_upload_size_message ();
2008-03-02 22:44:15 +01:00
//_debug_array($content);
2008-03-03 23:15:44 +01:00
2009-04-09 16:05:14 +02:00
$readonlys [ 'button[linkpaste]' ] = $readonlys [ 'button[paste]' ] = ! $clipboard_files || ! $dir_is_writable ;
2010-05-06 08:53:52 +02:00
$readonlys [ 'button[mailpaste]' ] = ! $clipboard_files || ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'felamimail' ]);
2008-03-02 22:44:15 +01:00
$readonlys [ 'button[createdir]' ] = ! $dir_is_writable ;
2009-03-19 21:12:35 +01:00
$readonlys [ 'button[symlink]' ] = ! $dir_is_writable ;
2008-03-03 13:16:11 +01:00
$readonlys [ 'button[upload]' ] = $readonlys [ 'upload' ] = ! $dir_is_writable ;
2008-04-16 09:07:31 +02:00
2008-03-03 13:16:11 +01:00
if ( $dir_is_writable || ! $content [ 'nm' ][ 'filter' ]) $sel_options [ 'action' ][ 'delete' ] = lang ( 'Delete' );
2008-03-02 22:44:15 +01:00
$sel_options [ 'action' ][ 'copy' ] = lang ( 'Copy to clipboard' );
2008-03-03 13:16:11 +01:00
if ( $dir_is_writable || ! $content [ 'nm' ][ 'filter' ]) $sel_options [ 'action' ][ 'cut' ] = lang ( 'Cut to clipboard' );
2010-05-06 08:53:52 +02:00
if ( $clipboard_files ) $sel_options [ 'action' ][ 'add' ] = lang ( 'Add to current clipboard' );
2008-04-16 09:07:31 +02:00
2008-03-03 13:16:11 +01:00
$sel_options [ 'filter' ] = array (
'1' => 'Current directory' ,
2008-10-06 19:43:42 +02:00
'2' => 'Directories sorted in' ,
2009-05-16 13:29:47 +02:00
'3' => 'Show hidden files' ,
2008-10-06 19:43:42 +02:00
'' => 'Files from subdirectories' ,
2008-03-03 13:16:11 +01:00
);
2010-05-06 08:53:52 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'felamimail' ])
{
$sel_options [ 'action' ][ 'mail' ] = lang ( 'Mail files' );
2010-05-09 16:08:36 +02:00
list ( $width , $height ) = explode ( 'x' , egw_link :: get_registry ( 'felamimail' , 'add_popup' ));
2010-05-06 08:53:52 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'java_script' ] .= " <script>
2010-05-09 16:08:36 +02:00
function open_mail ( attachments )
{
var link = '".egw::link(' / index . php ',array(' menuaction ' => ' felamimail . uicompose . compose '))."' ;
2010-09-06 11:29:05 +02:00
var i = 0 ;
2010-05-09 16:08:36 +02:00
if ( ! ( attachments instanceof Array )) attachments = [ attachments ];
for ( i = 0 ; i < attachments . length ; i ++ )
{
link += '&preset[file][]=' + encodeURIComponent ( 'vfs://default' + attachments [ i ]);
}
egw_openWindowCentered2 ( link , '_blank' , $width , $height , 'yes' );
}
2010-05-06 08:53:52 +02:00
function do_action ( selbox )
{
if ( selbox . value != '' )
{
if ( selbox . value == 'mail' && ( ids = get_selected_array ( selbox . form , '[rows][checked][]' )))
{
2010-05-09 16:08:36 +02:00
open_mail ( ids );
2010-05-06 08:53:52 +02:00
}
2010-12-21 00:23:44 +01:00
else if ( selbox . value == 'delete' )
{
if ( confirm ( '".lang(' Delete these files or directories ? ')."' )) selbox . form . submit ();
}
2010-05-06 08:53:52 +02:00
else
{
selbox . form . submit ();
}
selbox . value = '' ;
}
}
</ script > " ;
}
2010-08-31 15:53:06 +02:00
else
{
$tpl -> set_cell_attribute ( 'action' , 'onchange' , 'this.form.submit()' );
}
2008-03-02 22:44:15 +01:00
$tpl -> exec ( 'filemanager.filemanager_ui.index' , $content , $sel_options , $readonlys , array ( 'nm' => $content [ 'nm' ]));
}
2008-03-04 17:53:14 +01:00
2009-02-26 15:48:53 +01:00
/**
* Check if a file upload would overwrite an existing file and get a user confirmation in that case
*
* @ param string $id id of the input
* @ param string $name name ( incl . client - path ) of the file to upload
* @ param string $dir current vfs directory
* @ return string xajax output
*/
static function ajax_check_upload_target ( $id , $name , $dir )
{
$response = new xajaxResponse ();
//$response->addAlert(__METHOD__."('$id','$name','$dir')");
$name = explode ( '/' , str_replace ( '\\' , '/' , $name )); // in case of win clients
$name = array_pop ( $name );
2010-05-11 17:02:30 +02:00
// encode chars which special meaning in url/vfs (some like / get removed!)
$path = egw_vfs :: concat ( $dir , egw_vfs :: encodePathComponent ( $name ));
2009-02-26 15:48:53 +01:00
2009-03-31 13:30:12 +02:00
if ( egw_vfs :: deny_script ( $path ))
{
$response -> addAlert ( lang ( 'You are NOT allowed to upload a script!' ));
$response -> addScript ( " document.getElementById(' $id ').value=''; " );
}
elseif ( egw_vfs :: stat ( $path ))
2009-02-26 15:48:53 +01:00
{
if ( egw_vfs :: is_dir ( $path ))
{
$response -> addAlert ( lang ( " There's already a directory with that name! " ));
$response -> addScript ( " document.getElementById(' $id ').value=''; " );
}
else
{
2010-05-11 17:02:30 +02:00
$response -> addScript ( " if (!confirm(' " . addslashes ( lang ( 'Do you want to overwrite the existing file %1?' , urldecode ( $path ))) . " ')) document.getElementById(' $id ').value=''; " );
2009-02-26 15:48:53 +01:00
}
}
else
{
// do nothing new file
}
return $response -> getXML ();
}
2008-10-14 15:20:31 +02:00
/**
* Get the configured start directory for the current user
*
* @ return string
*/
static function get_home_dir ()
{
$start = '/home/' . $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ];
// check if user specified a valid startpath in his prefs --> use it
if (( $path = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'filemanager' ][ 'startfolder' ]) &&
$path [ 0 ] == '/' && egw_vfs :: is_dir ( $path ) && egw_vfs :: check_access ( $path , egw_vfs :: READABLE ))
{
$start = $path ;
}
return $start ;
}
2008-03-02 22:44:15 +01:00
/**
* Run a certain action with the selected file
*
* @ param string $action
* @ param array $selected selected pathes
* @ param mixed $dir = null current directory
2010-12-28 04:12:57 +01:00
* @ param int & $errs = null on return number of errors
* @ param int & $dirs = null on return number of dirs deleted
* @ param int & $files = null on return number of files deleted
2008-03-02 22:44:15 +01:00
* @ return string success or failure message displayed to the user
*/
2010-12-28 04:12:57 +01:00
static private function action ( $action , $selected , $dir = null , & $errs = null , & $files = null , & $dirs = null )
2008-03-02 22:44:15 +01:00
{
//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 )
{
2010-05-06 08:53:52 +02:00
case 'mail' :
2010-05-13 10:44:29 +02:00
throw new egw_exception_assertion_failed ( 'Implemented on clientside!' );
2010-05-06 08:53:52 +02:00
2008-03-02 22:44:15 +01:00
case 'delete' :
2010-12-28 04:12:57 +01:00
return self :: do_delete ( $selected , $errs , $files , $dirs );
2008-04-16 09:07:31 +02:00
2010-05-06 08:53:52 +02:00
case 'add' :
$files = egw_session :: appsession ( 'clipboard_files' , 'filemanager' );
egw_session :: appsession ( 'clipboard_files' , 'filemanager' , $files ? array_unique ( array_merge ( $files , $selected )) : $selected );
egw_session :: appsession ( 'clipboard_type' , 'filemanager' , 'copy' ); // always switch to copy, to be on the save side
return lang ( '%1 URLs %2 to clipboard.' , count ( $selected ), lang ( 'copied' ));
2008-03-02 22:44:15 +01:00
case 'copy' :
case 'cut' :
2009-12-01 15:51:13 +01:00
egw_session :: appsession ( 'clipboard_files' , 'filemanager' , $selected );
egw_session :: appsession ( 'clipboard_type' , 'filemanager' , $action );
2008-03-02 22:44:15 +01:00
return lang ( '%1 URLs %2 to clipboard.' , count ( $selected ), $action == 'copy' ? lang ( 'copied' ) : lang ( 'cut' ));
2008-04-16 09:07:31 +02:00
2008-03-02 22:44:15 +01:00
case 'copy_paste' :
foreach ( $selected as $path )
{
if ( ! egw_vfs :: is_dir ( $path ))
{
2008-04-14 07:54:10 +02:00
$to = egw_vfs :: concat ( $dir , egw_vfs :: basename ( $path ));
2008-03-04 08:35:05 +01:00
if ( $path != $to && egw_vfs :: copy ( $path , $to ))
2008-03-02 22:44:15 +01:00
{
++ $files ;
}
else
{
++ $errs ;
}
}
else
{
$len = strlen ( dirname ( $path ));
foreach ( egw_vfs :: find ( $path ) as $p )
{
$to = $dir . substr ( $p , $len );
2008-03-04 08:35:05 +01:00
if ( $to == $p ) // cant copy into itself!
{
++ $errs ;
continue ;
}
2008-03-02 22:44:15 +01:00
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 );
2008-04-16 09:07:31 +02:00
2010-12-28 04:12:57 +01:00
case 'move' :
if ( ! isset ( $dir )) $dir = array_pop ( $selected );
// fall throught
2008-03-02 22:44:15 +01:00
case 'cut_paste' :
foreach ( $selected as $path )
{
2010-12-28 04:12:57 +01:00
$to = egw_vfs :: is_dir ( $dir ) || count ( $selected ) > 1 ? egw_vfs :: concat ( $dir , egw_vfs :: basename ( $path )) : $dir ;
2008-03-04 08:35:05 +01:00
if ( $path != $to && egw_vfs :: rename ( $path , $to ))
2008-03-02 22:44:15 +01:00
{
++ $files ;
}
else
{
++ $errs ;
}
}
2010-12-28 04:12:57 +01:00
if ( $action == 'cut_paste' ) egw_session :: appsession ( 'clipboard_files' , 'filemanager' , false ); // cant move again
2008-03-02 22:44:15 +01:00
if ( $errs )
{
return lang ( '%1 errors moving (%2 files moved)!' , $errs , $files );
}
return lang ( '%1 files moved.' , $files );
2009-04-09 16:05:14 +02:00
case 'link_paste' :
foreach ( $selected as $path )
{
$to = egw_vfs :: concat ( $dir , egw_vfs :: basename ( $path ));
if ( $path != $to && egw_vfs :: symlink ( $path , $to ))
{
++ $files ;
}
else
{
++ $errs ;
}
}
$ret = lang ( '%1 elements linked.' , $files );
if ( $errs )
{
$ret = lang ( '%1 errors linking (%2)!' , $errs , $ret );
}
return $ret . " egw_vfs::symlink(' $to ',' $path ') " ;
2008-03-02 22:44:15 +01:00
}
return " Unknown action ' $action '! " ;
}
2010-12-28 04:12:57 +01:00
2010-09-24 20:55:36 +02:00
/**
* Delete selected files and return success or error message
2010-12-28 04:12:57 +01:00
*
2010-09-24 20:55:36 +02:00
* @ param array $selected
2010-12-28 04:12:57 +01:00
* @ param int & $errs = null on return number of errors
* @ param int & $dirs = null on return number of dirs deleted
* @ param int & $files = null on return number of files deleted
2010-09-24 20:55:36 +02:00
* @ return string
*/
2010-12-28 04:12:57 +01:00
public static function do_delete ( array $selected , & $errs = null , & $dirs = null , & $files = null )
2010-09-24 20:55:36 +02:00
{
$dirs = $files = $errs = 0 ;
// we first delete all selected links (and files)
// feeding the links to dirs to egw_vfs::find() deletes the content of the dirs, not just the link!
foreach ( $selected as $key => $path )
{
if ( ! egw_vfs :: is_dir ( $path ) || egw_vfs :: is_link ( $path ))
{
if ( egw_vfs :: unlink ( $path ))
{
++ $files ;
}
else
{
++ $errs ;
}
unset ( $selected [ $key ]);
}
}
if ( $selected ) // somethings left to delete
{
// some precaution to never allow to (recursivly) remove /, /apps or /home
foreach (( array ) $selected as $path )
{
if ( preg_match ( '/^\/?(home|apps|)\/*$/' , $path ))
{
2010-12-28 04:12:57 +01:00
$errs ++ ;
2010-09-24 20:55:36 +02:00
return lang ( " Cautiously rejecting to remove folder '%1'! " , urldecode ( $path ));
}
}
// now we use find to loop through all files and dirs: (selected only contains dirs now)
// - depth=true to get first the files and then the dir containing it
// - hidden=true to also return hidden files (eg. Thumbs.db), as we cant delete non-empty dirs
foreach ( egw_vfs :: find ( $selected , array ( 'depth' => true , 'hidden' => true )) as $path )
{
if (( $is_dir = egw_vfs :: is_dir ( $path ) && ! egw_vfs :: is_link ( $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 );
}
2008-03-02 22:44:15 +01:00
/**
* Callback to fetch the rows for the nextmatch widget
*
* @ param array $query
* @ param array & $rows
* @ param array & $readonlys
*/
function get_rows ( $query , & $rows , & $readonlys )
{
2009-05-06 17:15:39 +02:00
// show projectmanager sidebox for projectmanager path
if ( substr ( $query [ 'path' ], 0 , 20 ) == '/apps/projectmanager' && isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'projectmanager' ]))
{
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] = 'projectmanager' ;
}
2009-12-01 15:51:13 +01:00
egw_session :: appsession ( 'index' , 'filemanager' , $query );
2008-03-02 22:44:15 +01:00
2010-05-11 17:02:30 +02:00
// be tolerant with (in previous versions) not correct urlencoded pathes
if ( ! egw_vfs :: stat ( $query [ 'path' ], true ) && egw_vfs :: stat ( urldecode ( $query [ 'path' ])))
{
$query [ 'path' ] = urldecode ( $query [ 'path' ]);
}
2009-04-06 15:46:45 +02:00
if ( ! egw_vfs :: stat ( $query [ 'path' ], true ) || ! egw_vfs :: is_dir ( $query [ 'path' ]) || ! egw_vfs :: check_access ( $query [ 'path' ], egw_vfs :: READABLE ))
2008-03-02 22:44:15 +01:00
{
2008-10-05 19:07:36 +02:00
// we will leave here, since we are not allowed, or the location does not exist. Index must handle that, and give
2008-08-28 13:09:09 +02:00
// an appropriate message
2008-10-14 15:20:31 +02:00
egw :: redirect_link ( '/index.php' , array ( 'menuaction' => 'filemanager.filemanager_ui.index' ,
'path' => self :: get_home_dir (),
2010-05-11 17:02:30 +02:00
'msg' => lang ( 'The requested path %1 is not available.' , urldecode ( $query [ 'path' ])),
2008-10-14 15:20:31 +02:00
));
2008-03-02 22:44:15 +01:00
}
2008-03-03 13:16:11 +01:00
$rows = $dir_is_writable = array ();
if ( $query [ 'searchletter' ] && ! empty ( $query [ 'search' ]))
{
$namefilter = '/^' . $query [ 'searchletter' ] . '.*' . str_replace ( array ( '\\?' , '\\*' ), array ( '.{1}' , '.*' ), preg_quote ( $query [ 'search' ])) . '/i' ;
if ( $query [ 'searchletter' ] == strtolower ( $query [ 'search' ][ 0 ]))
{
$namefilter = '/^(' . $query [ 'searchletter' ] . '.*' . str_replace ( array ( '\\?' , '\\*' ), array ( '.{1}' , '.*' ), preg_quote ( $query [ 'search' ])) . '|' .
str_replace ( array ( '\\?' , '\\*' ), array ( '.{1}' , '.*' ), preg_quote ( $query [ 'search' ])) . ')/i' ;
}
}
elseif ( $query [ 'searchletter' ])
{
$namefilter = '/^' . $query [ 'searchletter' ] . '/i' ;
}
elseif ( ! empty ( $query [ 'search' ]))
{
$namefilter = '/' . str_replace ( array ( '\\?' , '\\*' ), array ( '.{1}' , '.*' ), preg_quote ( $query [ 'search' ])) . '/i' ;
}
2008-10-06 19:43:42 +02:00
foreach ( egw_vfs :: find ( $query [ 'path' ], array (
'mindepth' => 1 ,
'maxdepth' => $query [ 'filter' ] ? ( int )( boolean ) $query [ 'filter' ] : null ,
'dirsontop' => $query [ 'filter' ] <= 1 ,
'type' => $query [ 'filter' ] ? null : 'f' ,
'order' => $query [ 'order' ], 'sort' => $query [ 'sort' ],
'limit' => ( int ) $query [ 'num_rows' ] . ',' . ( int ) $query [ 'start' ],
'need_mime' => true ,
'name_preg' => $namefilter ,
2009-05-16 13:29:47 +02:00
'hidden' => $query [ 'filter' ] == 3 ,
2008-10-06 19:43:42 +02:00
), true ) as $path => $row )
{
//echo $path; _debug_array($row);
$rows [ ++ $n ] = $row ;
$path2n [ $path ] = $n ;
2008-10-05 19:07:36 +02:00
2008-10-06 19:43:42 +02:00
$dir = dirname ( $path );
if ( ! isset ( $dir_is_writable [ $dir ]))
2008-03-03 13:16:11 +01:00
{
2008-10-06 19:43:42 +02:00
$dir_is_writable [ $dir ] = egw_vfs :: is_writable ( $dir );
2008-03-03 13:16:11 +01:00
}
2010-09-14 19:03:12 +02:00
$path_quoted = str_replace ( array ( '"' , " ' " ), array ( '"' , " \\ ' " ), $path );
2008-10-06 19:43:42 +02:00
if ( ! $dir_is_writable [ $dir ])
2008-03-02 22:44:15 +01:00
{
2010-09-14 19:03:12 +02:00
$readonlys [ " delete[ $path_quoted ] " ] = true ; // no rights to delete the file
2008-03-02 22:44:15 +01:00
}
2010-12-28 04:12:57 +01:00
if ( egw_vfs :: is_dir ( $path ) || ! egw_vfs :: is_readable ( $path ) ||
2010-09-14 19:03:12 +02:00
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'felamimail' ])
2010-05-06 08:53:52 +02:00
{
2010-09-14 19:03:12 +02:00
$readonlys [ " mail[ $path_quoted ] " ] = true ;
2010-05-06 08:53:52 +02:00
}
2008-03-02 22:44:15 +01:00
}
2008-10-05 19:07:36 +02:00
// query comments and cf's for the displayed rows
$cols_to_show = explode ( ',' , $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'filemanager' ][ 'nextmatch-filemanager.index.rows' ]);
$cfs = config :: get_customfields ( 'filemanager' );
$all_cfs = in_array ( 'customfields' , $cols_to_show ) && $cols_to_show [ count ( $cols_to_show ) - 1 ][ 0 ] != '#' ;
if ( $path2n && ( in_array ( 'comment' , $cols_to_show ) || in_array ( 'customfields' , $cols_to_show )) &&
2008-10-05 21:01:49 +02:00
( $path2props = egw_vfs :: propfind ( array_keys ( $path2n ))))
2008-10-05 19:07:36 +02:00
{
foreach ( $path2props as $path => $props )
{
2008-10-21 11:08:37 +02:00
unset ( $row ); // fixes a weird problem with php5.1, does NOT happen with php5.2
2008-10-05 19:07:36 +02:00
$row =& $rows [ $path2n [ $path ]];
2009-02-27 11:22:28 +01:00
if ( ! is_array ( $props ) ) continue ;
2008-10-05 19:07:36 +02:00
foreach ( $props as $prop )
{
if ( ! $all_cfs && $prop [ 'name' ][ 0 ] == '#' && ! in_array ( $prop [ 'name' ], $cols_to_show )) continue ;
2008-10-05 21:01:49 +02:00
$row [ $prop [ 'name' ]] = strlen ( $prop [ 'val' ]) < 64 ? $prop [ 'val' ] : substr ( $prop [ 'val' ], 0 , 64 ) . ' ...' ;
2008-10-05 19:07:36 +02:00
}
}
}
2008-03-02 22:44:15 +01:00
//_debug_array($readonlys);
2009-05-06 17:15:39 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] == 'projectmanager' )
{
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'Projectmanager' ) . ' - ' . lang ( 'Filemanager' );
// we need our app.css file
if ( ! file_exists ( EGW_SERVER_ROOT . ( $css_file = '/filemanager/templates/' . $GLOBALS [ 'egw_info' ][ 'server' ][ 'template_set' ] . '/app.css' )))
{
$css_file = '/filemanager/templates/default/app.css' ;
}
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'css' ] .= " \n \t \t </style> \n \t \t " . '<link href="' . $GLOBALS [ 'egw_info' ][ 'server' ][ 'webserver_url' ] .
$css_file . '?' . filemtime ( EGW_SERVER_ROOT . $css_file ) . '" type="text/css" rel="StyleSheet" />' . " \n \t \t <style> \n \t \t \t " ;
}
else
{
2010-05-11 17:02:30 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'Filemanager' ) . ': ' . urldecode ( $query [ 'path' ]);
2009-05-06 17:15:39 +02:00
}
2008-03-03 08:53:43 +01:00
return egw_vfs :: $find_total ;
2008-03-02 22:44:15 +01:00
}
2008-04-16 09:07:31 +02:00
2008-03-03 23:15:44 +01:00
/**
* Preferences of a file / directory
*
* @ param array $content = null
2008-04-14 07:54:10 +02:00
* @ param string $msg = ''
2008-03-03 23:15:44 +01:00
*/
2008-04-14 07:54:10 +02:00
function file ( array $content = null , $msg = '' )
2008-03-03 23:15:44 +01:00
{
$tpl = new etemplate ( 'filemanager.file' );
2008-04-16 09:07:31 +02:00
2008-03-03 23:15:44 +01:00
if ( ! is_array ( $content ))
{
2010-04-22 19:38:01 +02:00
if ( isset ( $_GET [ 'msg' ]))
{
$msg .= $_GET [ 'msg' ];
}
2009-03-19 21:12:35 +01:00
if ( ! ( $path = $_GET [ 'path' ]) || ! ( $stat = egw_vfs :: lstat ( $path )))
2008-03-03 23:15:44 +01:00
{
2010-04-22 19:38:01 +02:00
$msg .= lang ( 'File or directory not found!' );
2008-03-03 23:15:44 +01:00
}
else
{
$content = $stat ;
$content [ 'name' ] = egw_vfs :: basename ( $path );
$content [ 'dir' ] = dirname ( $path );
$content [ 'path' ] = $path ;
$content [ 'hsize' ] = egw_vfs :: hsize ( $stat [ 'size' ]);
$content [ 'mime' ] = egw_vfs :: mime_content_type ( $path );
$content [ 'gid' ] *= - 1 ; // our widgets use negative gid's
2008-10-05 19:07:36 +02:00
if (( $props = egw_vfs :: propfind ( $path )))
{
2008-10-05 21:01:49 +02:00
foreach ( $props as $prop ) $content [ $prop [ 'name' ]] = $prop [ 'val' ];
2008-10-05 19:07:36 +02:00
}
2009-03-19 21:12:35 +01:00
if (( $content [ 'is_link' ] = egw_vfs :: is_link ( $path )))
{
$content [ 'symlink' ] = egw_vfs :: readlink ( $path );
}
2008-03-03 23:15:44 +01:00
}
2009-03-19 21:12:35 +01:00
$content [ 'tabs' ] = $_GET [ 'tabs' ];
if ( ! ( $content [ 'is_dir' ] = egw_vfs :: is_dir ( $path ) && ! egw_vfs :: is_link ( $path )))
2008-03-03 23:15:44 +01:00
{
$content [ 'perms' ][ 'executable' ] = ( int ) !! ( $content [ 'mode' ] & 0111 );
$mask = 6 ;
if ( preg_match ( '/^text/' , $content [ 'mime' ]) && $content [ 'size' ] < 100000 )
{
$content [ 'text_content' ] = file_get_contents ( egw_vfs :: PREFIX . $path );
}
}
else
{
2008-04-14 07:54:10 +02:00
//currently not implemented in backend $content['perms']['sticky'] = (int)!!($content['mode'] & 0x201);
2008-03-03 23:15:44 +01:00
$mask = 7 ;
}
foreach ( array ( 'owner' => 6 , 'group' => 3 , 'other' => 0 ) as $name => $shift )
{
$content [ 'perms' ][ $name ] = ( $content [ 'mode' ] >> $shift ) & $mask ;
}
2008-04-14 07:54:10 +02:00
$content [ 'is_owner' ] = egw_vfs :: has_owner_rights ( $path , $content );
2008-03-03 23:15:44 +01:00
}
else
{
2008-04-14 07:54:10 +02:00
//_debug_array($content);
2008-07-27 20:58:41 +02:00
$path =& $content [ 'path' ];
2008-04-16 09:07:31 +02:00
2008-04-14 07:54:10 +02:00
list ( $button ) = @ each ( $content [ 'button' ]); unset ( $content [ 'button' ]);
2010-05-11 17:02:30 +02:00
// need to check 'setup' button (submit button in sudo popup), as some browsers (eg. chrome) also fill the hidden field
if ( $button == 'sudo' && egw_vfs :: $is_root || $button == 'setup' && $content [ 'sudo' ][ 'user' ])
2008-11-09 17:33:09 +01:00
{
2010-05-11 17:02:30 +02:00
$msg = $this -> sudo ( $button == 'setup' ? $content [ 'sudo' ][ 'user' ] : '' , $content [ 'sudo' ][ 'passwd' ]) ?
lang ( 'Root access granted.' ) : ( $button == 'setup' && $content [ 'sudo' ][ 'user' ] ?
lang ( 'Wrong username or password!' ) : lang ( 'Root access stopped.' ));
2008-11-09 17:33:09 +01:00
unset ( $content [ 'sudo' ]);
$content [ 'is_owner' ] = egw_vfs :: has_owner_rights ( $path );
}
2008-04-14 07:54:10 +02:00
if ( in_array ( $button , array ( 'save' , 'apply' )))
2008-03-03 23:15:44 +01:00
{
2008-10-05 19:07:36 +02:00
$props = array ();
2008-04-14 07:54:10 +02:00
foreach ( $content [ 'old' ] as $name => $old_value )
2008-03-03 23:15:44 +01:00
{
2009-06-14 15:26:07 +02:00
if ( isset ( $content [ $name ]) && ( $old_value != $content [ $name ] ||
// do not check for modification, if modify_subs is checked!
2009-12-01 10:07:18 +01:00
$content [ 'modify_subs' ] && in_array ( $name , array ( 'uid' , 'gid' , 'perms' ))) &&
2009-11-28 16:12:26 +01:00
( $name != 'uid' || egw_vfs :: $is_root ))
2008-03-03 23:15:44 +01:00
{
2008-10-05 19:07:36 +02:00
if ( $name == 'name' )
{
2008-11-16 11:18:19 +01:00
$to = egw_vfs :: concat ( $content [ 'dir' ], $content [ 'name' ]);
if ( file_exists ( egw_vfs :: PREFIX . $to ) && $content [ 'confirm_overwrite' ] !== $to )
{
$tpl -> set_validation_error ( 'name' , lang ( " There's already a file with that name! " ) . '<br />' .
lang ( 'To overwrite the existing file store again.' , lang ( $button )));
$content [ 'confirm_overwrite' ] = $to ;
if ( $button == 'save' ) $button = 'apply' ;
continue ;
}
if ( egw_vfs :: rename ( $path , $to ))
2008-10-05 19:07:36 +02:00
{
2010-05-11 22:30:13 +02:00
$msg .= lang ( 'Renamed %1 to %2.' , urldecode ( basename ( $path )), urldecode ( basename ( $to ))) . ' ' ;
2008-10-05 19:07:36 +02:00
$content [ 'old' ][ 'name' ] = $content [ $name ];
$path = $to ;
2009-12-01 15:51:13 +01:00
$content [ 'mime' ] = mime_magic :: filename2mime ( $path ); // recheck mime type
2010-12-28 04:12:57 +01:00
$refresh_path = egw_vfs :: dirname ( $path ); // for renames, we have to refresh the parent
2008-10-05 19:07:36 +02:00
}
else
{
2010-05-11 22:30:13 +02:00
$msg .= lang ( 'Rename of %1 to %2 failed!' , urldecode ( basename ( $path )), urldecode ( basename ( $to ))) . ' ' ;
2009-03-31 13:30:12 +02:00
if ( egw_vfs :: deny_script ( $to ))
{
$msg .= lang ( 'You are NOT allowed to upload a script!' ) . ' ' ;
}
2008-10-05 19:07:36 +02:00
}
}
elseif ( $name [ 0 ] == '#' || $name == 'comment' )
2008-04-14 07:54:10 +02:00
{
2008-10-05 21:01:49 +02:00
$props [] = array ( 'name' => $name , 'val' => $content [ $name ] ? $content [ $name ] : null );
2008-04-14 07:54:10 +02:00
}
2008-10-05 19:07:36 +02:00
else
{
static $name2cmd = array ( 'uid' => 'chown' , 'gid' => 'chgrp' , 'perms' => 'chmod' );
$cmd = array ( 'egw_vfs' , $name2cmd [ $name ]);
$value = $name == 'perms' ? self :: perms2mode ( $content [ 'perms' ]) : $content [ $name ];
2008-11-09 17:33:09 +01:00
if ( $content [ 'modify_subs' ])
2008-10-05 19:07:36 +02:00
{
2008-11-09 17:33:09 +01:00
if ( $name == 'perms' )
{
$changed = egw_vfs :: find ( $path , array ( 'type' => 'd' ), $cmd , array ( $value ));
$changed += egw_vfs :: find ( $path , array ( 'type' => 'f' ), $cmd , array ( $value & 0666 )); // no execute for files
}
else
{
$changed = egw_vfs :: find ( $path , null , $cmd , array ( $value ));
}
$ok = $failed = 0 ;
foreach ( $changed as $p => $r )
{
if ( $r )
{
++ $ok ;
}
else
{
++ $failed ;
}
}
if ( $ok && ! $failed )
{
2009-06-14 15:26:07 +02:00
if ( ! $perm_changed ++ ) $msg .= lang ( 'Permissions of %1 changed.' , $path . ' ' . lang ( 'and all it\'s childeren' ));
2008-11-12 18:04:38 +01:00
$content [ 'old' ][ $name ] = $content [ $name ];
2008-11-09 17:33:09 +01:00
}
elseif ( $failed )
{
2009-06-14 15:26:07 +02:00
if ( ! $perm_failed ++ ) $msg .= lang ( 'Failed to change permissions of %1!' , $path . lang ( 'and all it\'s childeren' ) .
2008-11-09 17:33:09 +01:00
( $ok ? ' (' . lang ( '%1 failed, %2 succeded' , $failed , $ok ) . ')' : '' ));
}
2008-10-05 19:07:36 +02:00
}
2008-11-09 17:33:09 +01:00
elseif ( call_user_func_array ( $cmd , array ( $path , $value )))
2008-10-05 19:07:36 +02:00
{
2008-11-09 17:33:09 +01:00
$msg .= lang ( 'Permissions of %1 changed.' , $path );
2008-11-12 18:04:38 +01:00
$content [ 'old' ][ $name ] = $content [ $name ];
2008-10-05 19:07:36 +02:00
}
else
{
2008-11-09 17:33:09 +01:00
$msg .= lang ( 'Failed to change permissions of %1!' , $path );
2008-10-05 19:07:36 +02:00
}
}
}
}
if ( $props )
{
if ( egw_vfs :: proppatch ( $path , $props ))
{
foreach ( $props as $prop )
{
2008-10-05 21:01:49 +02:00
$content [ 'old' ][ $prop [ 'name' ]] = $prop [ 'val' ];
2008-10-05 19:07:36 +02:00
}
$msg .= lang ( 'Properties saved.' );
}
else
{
$msg .= lang ( 'Saving properties failed!' );
2008-04-14 07:54:10 +02:00
}
}
}
elseif ( $content [ 'eacl' ] && $content [ 'is_owner' ])
{
if ( $content [ 'eacl' ][ 'delete' ])
{
list ( $ino_owner ) = each ( $content [ 'eacl' ][ 'delete' ]);
2008-11-13 11:48:06 +01:00
list ( $ino , $owner ) = explode ( '-' , $ino_owner , 2 ); // $owner is a group and starts with a minus!
2008-04-14 07:54:10 +02:00
$msg .= egw_vfs :: eacl ( $path , null , $owner ) ? lang ( 'ACL deleted.' ) : lang ( 'Error deleting the ACL entry!' );
}
elseif ( $button == 'eacl' )
{
if ( ! $content [ 'eacl' ][ 'owner' ])
{
$msg .= lang ( 'You need to select an owner!' );
}
else
{
$msg .= egw_vfs :: eacl ( $path , $content [ 'eacl' ][ 'rights' ], $content [ 'eacl' ][ 'owner' ]) ?
lang ( 'ACL added.' ) : lang ( 'Error adding the ACL!' );
2008-03-03 23:15:44 +01:00
}
}
}
2010-12-28 04:12:57 +01:00
$js = " opener.egw_refresh(' " . str_replace ( " ' " , " \\ ' " , $msg ) . " ','filemanager',' " .
str_replace ( " ' " , " \\ ' " , $refresh_path ? $refresh_path : $path ) . " ','edit'); " ;
2008-04-14 07:54:10 +02:00
if ( $button == 'save' ) $js .= " window.close(); " ;
2008-03-03 23:15:44 +01:00
echo " <html> \n <body> \n <script> \n $js\n </script> \n </body> \n </html> \n " ;
2009-12-01 15:51:13 +01:00
if ( $button == 'save' ) common :: egw_exit ();
2008-03-03 23:15:44 +01:00
}
2009-03-19 21:12:35 +01:00
if ( $content [ 'is_link' ] && ! egw_vfs :: stat ( $path ))
{
$msg .= ( $msg ? " \n " : '' ) . lang ( 'Link target %1 not found!' , $content [ 'symlink' ]);
}
2009-12-01 15:51:13 +01:00
$content [ 'link' ] = egw :: link ( egw_vfs :: download_url ( $path ));
$content [ 'icon' ] = egw_vfs :: mime_icon ( $content [ 'mime' ]);
2008-04-14 07:54:10 +02:00
$content [ 'msg' ] = $msg ;
2008-03-03 23:15:44 +01:00
if (( $readonlys [ 'uid' ] = ! egw_vfs :: $is_root ) && ! $content [ 'uid' ]) $content [ 'ro_uid_root' ] = 'root' ;
// only owner can change group & perms
2008-04-14 07:54:10 +02:00
if (( $readonlys [ 'gid' ] = ! $content [ 'is_owner' ] ||
2008-03-03 23:15:44 +01:00
parse_url ( egw_vfs :: resolve_url ( $content [ 'path' ]), PHP_URL_SCHEME ) == 'oldvfs' )) // no uid, gid or perms in oldvfs
{
if ( ! $content [ 'gid' ]) $content [ 'ro_gid_root' ] = 'root' ;
foreach ( $content [ 'perms' ] as $name => $value )
{
$readonlys [ 'perms[' . $name . ']' ] = true ;
}
}
2008-11-09 17:33:09 +01:00
$readonlys [ 'name' ] = $path == '/' || ! egw_vfs :: is_writable ( $content [ 'dir' ]);
2008-10-05 19:07:36 +02:00
$readonlys [ 'comment' ] = ! egw_vfs :: is_writable ( $path );
2009-03-19 21:12:35 +01:00
$readonlys [ 'tabs' ][ 'preview' ] = $readonlys [ 'tabs' ][ 'perms' ] = $content [ 'is_link' ];
2008-04-16 09:07:31 +02:00
2008-11-09 17:33:09 +01:00
// if neither owner nor is writable --> disable save&apply
$readonlys [ 'button[save]' ] = $readonlys [ 'button[apply]' ] = ! $content [ 'is_owner' ] && ! egw_vfs :: is_writable ( $path );
2008-10-05 19:07:36 +02:00
if ( ! ( $cfs = config :: get_customfields ( 'filemanager' )))
{
2009-03-19 21:12:35 +01:00
$readonlys [ 'tabs' ][ 'custom' ] = true ;
2008-10-05 19:07:36 +02:00
}
elseif ( ! egw_vfs :: is_writable ( $path ))
{
foreach ( $cfs as $name => $data )
{
$readonlys [ '#' . $name ] = true ;
}
}
2009-03-19 21:12:35 +01:00
$readonlys [ 'tabs' ][ 'eacl' ] = true ; // eacl off by default
2008-03-03 23:15:44 +01:00
if ( $content [ 'is_dir' ])
{
2009-03-19 21:12:35 +01:00
$readonlys [ 'tabs' ][ 'preview' ] = true ; // no preview tab for dirs
2008-04-14 07:54:10 +02:00
$sel_options [ 'rights' ] = $sel_options [ 'owner' ] = $sel_options [ 'group' ] = $sel_options [ 'other' ] = array (
2008-03-03 23:15:44 +01:00
7 => lang ( 'Display and modification of content' ),
5 => lang ( 'Display of content' ),
0 => lang ( 'No access' ),
);
2008-04-14 07:54:10 +02:00
if (( $content [ 'eacl' ] = egw_vfs :: get_eacl ( $content [ 'path' ])) !== false ) // backend supports eacl
{
2009-03-19 21:12:35 +01:00
unset ( $readonlys [ 'tabs' ][ 'eacl' ]); // --> switch the tab on again
2008-04-14 07:54:10 +02:00
foreach ( $content [ 'eacl' ] as & $eacl )
{
$eacl [ 'path' ] = parse_url ( $eacl [ 'path' ], PHP_URL_PATH );
2008-04-16 09:07:31 +02:00
$readonlys [ 'delete[' . $eacl [ 'ino' ] . '-' . $eacl [ 'owner' ] . ']' ] = $eacl [ 'ino' ] != $content [ 'ino' ] ||
2008-04-14 07:54:10 +02:00
$eacl [ 'path' ] != $content [ 'path' ] || ! $content [ 'is_owner' ];
}
array_unshift ( $content [ 'eacl' ], false ); // make the keys start with 1, not 0
2009-08-26 12:04:21 +02:00
$content [ 'eacl' ][ 'owner' ] = 0 ;
$content [ 'eacl' ][ 'rights' ] = 5 ;
2008-04-14 07:54:10 +02:00
}
2008-03-03 23:15:44 +01:00
}
else
{
$sel_options [ 'owner' ] = $sel_options [ 'group' ] = $sel_options [ 'other' ] = array (
6 => lang ( 'Read & write access' ),
4 => lang ( 'Read access only' ),
0 => lang ( 'No access' ),
2008-04-14 07:54:10 +02:00
);
2008-03-03 23:15:44 +01:00
}
$preserve = $content ;
if ( ! isset ( $preserve [ 'old' ]))
{
$preserve [ 'old' ] = array (
'perms' => $content [ 'perms' ],
'name' => $content [ 'name' ],
'uid' => $content [ 'uid' ],
'gid' => $content [ 'gid' ],
2008-10-05 19:07:36 +02:00
'comment' => ( string ) $content [ 'comment' ],
2008-03-03 23:15:44 +01:00
);
2008-10-05 19:07:36 +02:00
if ( $cfs ) foreach ( $cfs as $name => $data )
{
$preserve [ 'old' ][ '#' . $name ] = ( string ) $content [ '#' . $name ];
}
2008-03-03 23:15:44 +01:00
}
2008-11-09 17:33:09 +01:00
if ( egw_vfs :: $is_root )
{
$sudo_button =& $tpl -> get_widget_by_name ( 'sudo' );
$sudo_button = etemplate :: empty_cell ( 'button' , 'button[sudo]' , array (
'label' => 'Logout' ,
'help' => 'Log out as superuser' ,
'align' => 'right' ,
));
}
2010-04-22 19:38:01 +02:00
if (( $extra_tab = egw_vfs :: getExtraInfo ( $path , $content )))
2010-03-23 21:44:17 +01:00
{
$tabs =& $tpl -> get_widget_by_name ( 'tabs=general|perms|eacl|preview|custom' );
$tabs [ 'name' ] .= '|' . $extra_tab [ 'name' ];
$tabs [ 'label' ] .= '|' . $extra_tab [ 'label' ];
if ( $extra_tab [ 'data' ] && is_array ( $extra_tab [ 'data' ]))
{
$content += $extra_tab [ 'data' ];
}
2010-05-13 13:59:16 +02:00
if ( $extra_tab [ 'readonlys' ] && is_array ( $extra_tab [ 'readonlys' ]))
{
$readonlys += $extra_tab [ 'readonlys' ];
}
2010-03-23 21:44:17 +01:00
}
2008-03-03 23:15:44 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'java_script' ] = " <script>window.focus();</script> \n " ;
2010-05-11 17:02:30 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'Preferences' ) . ' ' . urldecode ( $path );
2008-03-03 23:15:44 +01:00
$tpl -> exec ( 'filemanager.filemanager_ui.file' , $content , $sel_options , $readonlys , $preserve , 2 );
}
2008-04-16 09:07:31 +02:00
2010-12-28 04:12:57 +01:00
/**
* Run given action on given path ( es ) and return array / object with values for keys 'msg' , 'errs' , 'dirs' , 'files'
*
* @ param string $action eg . 'delete' , ...
* @ param string $path
* @ see self :: action ()
*/
public static function ajax_action ( $action , $path )
{
$response = egw_json_response :: get ();
$arr = array (
'msg' => '' ,
'errs' => 0 ,
'dirs' => 0 ,
'files' => 0 ,
);
$selected = func_get_args ();
$action = array_shift ( $selected );
$arr [ 'msg' ] = self :: action ( $action , $selected , null , $arr [ 'errs' ], $arr [ 'dirs' ], $arr [ 'files' ]);
$response -> data ( $arr );
error_log ( __METHOD__ . " (' $action ', " . array2string ( $selected ) . ') returning ' . array2string ( $arr ));
}
2008-03-03 23:15:44 +01:00
/**
* Convert perms array back to integer mode
*
* @ param array $perms with keys owner , group , other , executable , sticky
* @ return int
*/
private function perms2mode ( array $perms )
{
2008-11-09 17:33:09 +01:00
$mode = $perms [ 'owner' ] << 6 | $perms [ 'group' ] << 3 | $perms [ 'other' ];
2008-03-03 23:15:44 +01:00
if ( $mode [ 'executable' ])
{
$mode |= 0111 ;
}
if ( $mode [ 'sticky' ])
{
$mode |= 0x201 ;
}
return $mode ;
}
2008-08-27 13:17:00 +02:00
}