2009-04-15 23:11:57 +02:00
< ? php
/**
2009-04-17 08:28:19 +02:00
* eGroupWare - Filemanager - select file to open or save dialog
2009-04-15 23:11:57 +02:00
*
* @ link http :// www . egroupware . org
* @ package filemanager
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
2012-10-31 19:00:28 +01:00
* @ copyright ( c ) 2009 - 2012 by Ralf Becker < RalfBecker - AT - outdoor - training . de >
2009-04-15 23:11:57 +02:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2009-04-17 08:28:19 +02:00
/**
* Select file to open or save dialog
*
* This dialog can be called from applications to open or store files from the VFS .
*
* There are the following ( $_GET ) parameters :
* - menuaction = filemanager . filemanager_select . select ( required )
* - mode = ( open | open - multiple | saveas | select - dir ) ( required )
* - method = app . class . method ( required callback , gets called with id and selected file ( s ))
* - id =... ( optional parameter passed to callback )
* - path =... ( optional start path in VFS )
* - mime =... ( optional mime - type to limit display to given type )
* - label =... ( optional label for submit button , default " Open " )
*
* The application calls this method in a popup with size : 640 x580 px
* After the user selected one or more files ( depending on the mode parameter ), the " method " callback gets
* called on server ( ! ) side . Parameters are the id plus the selected files as 1. and 2. parameter .
* The callback returns javascript to eg . update it ' s UI AND ( ! ) to close the current popup ( " window.close(); " ) .
*/
2009-04-15 23:11:57 +02:00
class filemanager_select
{
/**
* Methods callable via menuaction
*
* @ var array
*/
var $public_functions = array (
'select' => true ,
);
/**
* Constructor
*
*/
function __construct ()
{
2013-11-28 13:02:04 +01:00
// tell framework felamimail needs eval and inline javascript :(
egw_framework :: csp_script_src_attrs ( array ( 'unsafe-eval' , 'unsafe-inline' ));
2009-04-15 23:11:57 +02:00
// strip slashes from _GET parameters, if someone still has magic_quotes_gpc on
if ( get_magic_quotes_gpc () && $_GET )
{
$_GET = etemplate :: array_stripslashes ( $_GET );
}
}
/**
2009-04-17 08:28:19 +02:00
* File selector
2009-04-15 23:11:57 +02:00
*
2009-04-17 08:28:19 +02:00
* @ param array $content
2009-04-15 23:11:57 +02:00
*/
function select ( array $content = null )
{
if ( ! is_array ( $content ))
{
$content = array ();
2010-05-27 15:30:40 +02:00
// recover from a failed upload in CkEditor, eg. > max_uploadsize
if ( $_GET [ 'failed_upload' ] && $_GET [ 'msg' ])
{
$content [ 'msg' ] = $_GET [ 'msg' ];
$_GET [ 'mode' ] = 'open' ;
$_GET [ 'method' ] = 'ckeditor_return' ;
$_GET [ 'CKEditorFuncNum' ] = egw_cache :: getSession ( 'filemanager' , 'ckeditorfuncnum' );
}
2009-04-15 23:11:57 +02:00
$content [ 'mode' ] = $_GET [ 'mode' ];
if ( ! in_array ( $content [ 'mode' ], array ( 'open' , 'open-multiple' , 'saveas' , 'select-dir' )))
{
throw new egw_exception_wrong_parameter ( " Wrong or unset required mode parameter! " );
}
$content [ 'path' ] = $_GET [ 'path' ];
2010-05-26 11:30:55 +02:00
if ( empty ( $content [ 'path' ]))
2009-04-15 23:11:57 +02:00
{
2009-04-17 09:37:12 +02:00
$content [ 'path' ] = egw_session :: appsession ( 'select_path' , 'filemanger' );
2009-04-15 23:11:57 +02:00
}
2009-04-17 10:22:31 +02:00
$content [ 'name' ] = ( string ) $_GET [ 'name' ];
2009-04-15 23:11:57 +02:00
$content [ 'method' ] = $_GET [ 'method' ];
2010-05-25 09:50:59 +02:00
if ( $content [ 'method' ] == 'ckeditor_return' )
{
if ( isset ( $_GET [ 'CKEditorFuncNum' ]) && is_numeric ( $_GET [ 'CKEditorFuncNum' ]))
{
2010-05-27 15:30:40 +02:00
egw_cache :: setSession ( 'filemanager' , 'ckeditorfuncnum' ,
$content [ 'ckeditorfuncnum' ] = $_GET [ 'CKEditorFuncNum' ]);
2010-05-25 09:50:59 +02:00
}
else
2010-05-27 15:30:40 +02:00
{
2010-05-25 09:50:59 +02:00
throw new egw_exception_wrong_parameter ( " chkeditor_return has been specified as a method but some parameters are missing or invalid. " );
2010-05-27 15:30:40 +02:00
}
2010-05-25 09:50:59 +02:00
}
2009-04-15 23:11:57 +02:00
$content [ 'id' ] = $_GET [ 'id' ];
$content [ 'label' ] = isset ( $_GET [ 'label' ]) ? $_GET [ 'label' ] : lang ( 'Open' );
2009-04-17 08:28:19 +02:00
if (( $content [ 'options-mime' ] = isset ( $_GET [ 'mime' ])))
{
2013-10-04 11:28:10 +02:00
$sel_options [ 'mime' ] = array ();
2009-04-17 08:28:19 +02:00
foreach (( array ) $_GET [ 'mime' ] as $key => $value )
{
if ( is_numeric ( $key ))
{
2013-10-04 11:28:10 +02:00
$sel_options [ 'mime' ][ $value ] = lang ( '%1 files' , strtoupper ( mime_magic :: mime2ext ( $value ))) . ' (' . $value . ')' ;
2009-04-17 08:28:19 +02:00
}
else
{
2013-10-04 11:28:10 +02:00
$sel_options [ 'mime' ][ $key ] = lang ( '%1 files' , strtoupper ( $value )) . ' (' . $key . ')' ;
2009-04-17 08:28:19 +02:00
}
}
2014-02-10 19:37:51 +01:00
2013-10-04 11:28:10 +02:00
list ( $content [ 'mime' ]) = each ( $sel_options [ 'mime' ]);
error_log ( array2string ( $content [ 'options-mime' ]));
2009-04-17 08:28:19 +02:00
}
2009-04-15 23:11:57 +02:00
}
2009-04-17 09:37:12 +02:00
elseif ( isset ( $content [ 'button' ]))
2009-04-15 23:11:57 +02:00
{
2009-04-17 09:37:12 +02:00
list ( $button ) = each ( $content [ 'button' ]);
unset ( $content [ 'button' ]);
2009-04-15 23:11:57 +02:00
switch ( $button )
{
case 'up' :
if ( $content [ 'path' ] != '/' ) $content [ 'path' ] = egw_vfs :: dirname ( $content [ 'path' ]);
break ;
case 'home' :
$content [ 'path' ] = filemanager_ui :: get_home_dir ();
break ;
2012-10-31 19:20:34 +01:00
case 'createdir' :
if ( !@ egw_vfs :: mkdir ( $content [ 'path' ], null , STREAM_MKDIR_RECURSIVE ))
{
$content [ 'msg' ] = ! egw_vfs :: is_writable ( dirname ( $content [ 'path' ])) ?
lang ( 'Permission denied!' ) : lang ( 'Failed to create directory!' );
$content [ 'path' ] = $content [ 'old_path' ];
}
break ;
2009-04-15 23:11:57 +02:00
case 'ok' :
2010-05-25 09:50:59 +02:00
$copy_result = null ;
2013-10-04 11:28:10 +02:00
if ( isset ( $content [ 'file_upload' ][ 'name' ]) && file_exists ( $content [ 'file_upload' ][ 'tmp_name' ]))
2010-05-25 09:50:59 +02:00
{
//Set the "content" name filed accordingly to the uploaded file
2010-05-27 15:30:40 +02:00
// encode chars which special meaning in url/vfs (some like / get removed!)
$content [ 'name' ] = egw_vfs :: encodePathComponent ( $content [ 'file_upload' ][ 'name' ]);
2010-05-25 09:50:59 +02:00
$to_path = egw_vfs :: concat ( $content [ 'path' ], $content [ 'name' ]);
2010-11-09 13:59:27 +01:00
2010-05-27 15:30:40 +02:00
$copy_result = ( egw_vfs :: is_writable ( $content [ 'path' ]) || egw_vfs :: is_writable ( $to )) &&
copy ( $content [ 'file_upload' ][ 'tmp_name' ], egw_vfs :: PREFIX . $to_path );
2010-05-25 09:50:59 +02:00
}
2010-11-09 13:59:27 +01:00
//Break on an error condition
2010-05-25 09:50:59 +02:00
if ((( $content [ 'mode' ] == 'open' || $content [ 'mode' ] == 'saveas' ) && ( $content [ 'name' ] == '' )) || ( $copy_result === false ))
{
if ( $copy_result === false )
2010-05-27 15:30:40 +02:00
{
2010-11-30 15:29:06 +01:00
$content [ 'msg' ] = lang ( 'Error uploading file!' );
2010-05-27 15:30:40 +02:00
}
2010-05-25 09:50:59 +02:00
else
2010-05-27 15:30:40 +02:00
{
2010-11-30 15:29:06 +01:00
$content [ 'msg' ] = lang ( 'Filename must not be empty!' );
2010-05-27 15:30:40 +02:00
}
2010-05-25 09:50:59 +02:00
$content [ 'name' ] = '' ;
break ;
}
2009-04-15 23:11:57 +02:00
switch ( $content [ 'mode' ])
{
case 'open-multiple' :
foreach (( array ) $content [ 'dir' ][ 'selected' ] as $name )
{
$files [] = egw_vfs :: concat ( $content [ 'path' ], $name );
}
2010-05-25 09:50:59 +02:00
//Add an uploaded file to the files result array2string
2010-05-27 15:30:40 +02:00
if ( $copy_result === true ) $files [] = $to_path ;
2009-04-15 23:11:57 +02:00
break ;
2010-05-27 15:30:40 +02:00
2009-04-15 23:11:57 +02:00
case 'select-dir' :
$files = $content [ 'path' ];
break ;
2010-05-27 15:30:40 +02:00
2009-04-15 23:11:57 +02:00
default :
$files = egw_vfs :: concat ( $content [ 'path' ], $content [ 'name' ]);
break ;
}
2010-05-25 09:50:59 +02:00
2013-10-01 17:40:14 +02:00
if ( $content [ 'method' ] && $content [ 'method' ] != 'ckeditor_return' )
2010-05-27 15:30:40 +02:00
{
2010-05-25 09:50:59 +02:00
$js = ExecMethod2 ( $content [ 'method' ], $content [ 'id' ], $files );
2010-05-27 15:30:40 +02:00
}
2013-10-01 17:40:14 +02:00
else if ( $content [ 'method' ] == 'ckeditor_return' )
2010-05-27 15:30:40 +02:00
{
2010-09-07 13:57:31 +02:00
$download_url = egw_vfs :: download_url ( egw_vfs :: concat ( $content [ 'path' ], $content [ 'name' ]));
if ( $download_url [ 0 ] == '/' ) $download_url = egw :: link ( $download_url );
2010-05-25 09:50:59 +02:00
$js = " window.opener.CKEDITOR.tools.callFunction( " .
$content [ 'ckeditorfuncnum' ] . " ,' " .
2010-09-07 13:57:31 +02:00
htmlspecialchars ( $download_url ) . " ', " .
2010-05-25 09:50:59 +02:00
" ''); \n window.close(); " ;
2010-05-27 15:30:40 +02:00
}
2013-11-28 13:02:04 +01:00
if ( egw_json_response :: isJSONResponse () && ! ( $content [ 'method' ] == 'ckeditor_return' ))
2013-10-01 17:40:14 +02:00
{
$response = egw_json_response :: get ();
if ( $js )
{
$response -> script ( $js );
}
// Ahh!
// The vfs-select widget looks for this
$response -> script ( 'this.selected_files = ' . json_encode ( $files ) . '; this.close();' );
}
else
{
header ( 'Content-type: text/html; charset=' . translation :: charset ());
echo " <html> \n <head> \n <script type='text/javascript'> \n $js\n </script> \n </head> \n </html> \n " ;
}
2010-05-27 15:30:40 +02:00
common :: egw_exit ();
2009-04-15 23:11:57 +02:00
}
2014-02-10 19:37:51 +01:00
2013-10-04 11:28:10 +02:00
$sel_options [ 'mime' ] = $content [ 'options-mime' ];
2009-04-15 23:11:57 +02:00
}
2009-04-17 09:37:12 +02:00
elseif ( isset ( $content [ 'apps' ]))
{
list ( $app ) = each ( $content [ 'apps' ]);
if ( $app == 'home' ) $content [ 'path' ] = filemanager_ui :: get_home_dir ();
}
2010-05-25 09:50:59 +02:00
//Deactivate the opload field if the current directory is not writeable or
//we're currently not in the single file open mode.
2010-05-26 11:30:55 +02:00
$content [ 'no_upload' ] = ! egw_vfs :: is_writable ( $content [ 'path' ]) ||
! in_array ( $content [ 'mode' ], array ( 'open' ));
2010-05-25 09:50:59 +02:00
2009-04-17 09:37:12 +02:00
$content [ 'apps' ] = array_keys ( self :: get_apps ());
2009-05-11 22:43:18 +02:00
if ( isset ( $app ))
2009-04-17 09:37:12 +02:00
{
2009-05-11 22:43:18 +02:00
$content [ 'path' ] = '/apps/' . ( isset ( $content [ 'apps' ][ $app ]) ? $content [ 'apps' ][ $app ] : $app );
}
2014-02-20 18:47:38 +01:00
// Set a flag for easy detection as we go
$favorites_flag = substr ( $content [ 'path' ], 0 , strlen ( '/apps/favorites' )) == '/apps/favorites' ;
if ( ! $favorites_flag && ( ! $content [ 'path' ] || ! egw_vfs :: is_dir ( $content [ 'path' ])))
2009-04-17 09:37:12 +02:00
{
$content [ 'path' ] = filemanager_ui :: get_home_dir ();
}
2013-10-01 17:40:14 +02:00
$tpl = new etemplate_new ( 'filemanager.select' );
2012-10-31 19:00:28 +01:00
$et2 = class_exists ( 'etemplate_widget' , false ) && is_a ( $tpl , 'etemplate_widget' );
2014-02-20 18:47:38 +01:00
if ( $favorites_flag )
{
// Display favorites as if they were folders
$files = array ();
$favorites = egw_favorites :: get_favorites ( 'filemanager' );
$n = 0 ;
foreach ( $favorites as $f_id => $favorite )
{
$path = $favorite [ 'state' ][ 'path' ];
// Just directories
if ( ! $path ) continue ;
if ( $path == $content [ 'path' ]) continue ; // remove directory itself
$mime = egw_vfs :: mime_content_type ( $path );
$content [ 'dir' ][ $n ] = array (
'name' => $favorite [ 'name' ],
'path' => $path ,
'mime' => $mime ,
);
if ( $content [ 'mode' ] == 'open-multiple' )
{
$readonlys [ 'selected[' . $favorite [ 'name' ] . ']' ] = true ;
}
++ $n ;
}
}
else if ( ! ( $files = egw_vfs :: find ( $content [ 'path' ], array (
2010-12-31 15:31:50 +01:00
'dirsontop' => true ,
2010-11-09 13:59:27 +01:00
'order' => 'name' ,
'sort' => 'ASC' ,
'maxdepth' => 1 ,
))))
2009-04-15 23:11:57 +02:00
{
$content [ 'msg' ] = lang ( " Can't open directory %1! " , $content [ 'path' ]);
}
else
{
$n = 0 ;
$content [ 'dir' ] = array ( 'mode' => $content [ 'mode' ]);
2010-11-09 13:59:27 +01:00
foreach ( $files as $path )
2009-04-15 23:11:57 +02:00
{
2011-08-04 17:44:52 +02:00
if ( $path == $content [ 'path' ]) continue ; // remove directory itself
2010-11-09 13:59:27 +01:00
$name = egw_vfs :: basename ( $path );
2009-04-15 23:11:57 +02:00
$is_dir = egw_vfs :: is_dir ( $path );
2012-07-03 00:57:02 +02:00
$mime = egw_vfs :: mime_content_type ( $path );
if ( $content [ 'mime' ] && ! $is_dir && $mime != $content [ 'mime' ])
2009-04-17 08:28:19 +02:00
{
continue ; // does not match mime-filter --> ignore
}
2009-04-15 23:11:57 +02:00
$content [ 'dir' ][ $n ] = array (
'name' => $name ,
'path' => $path ,
2012-07-03 00:57:02 +02:00
'mime' => $mime ,
2009-04-15 23:11:57 +02:00
);
if ( $is_dir && $content [ 'mode' ] == 'open-multiple' )
{
$readonlys [ 'selected[' . $name . ']' ] = true ;
}
++ $n ;
}
2010-05-19 14:25:33 +02:00
if ( ! $n ) $readonlys [ 'selected[]' ] = true ; // remove checkbox from empty line
2009-04-15 23:11:57 +02:00
}
2012-10-31 19:20:34 +01:00
$readonlys [ 'button[createdir]' ] = ! egw_vfs :: is_writable ( $content [ 'path' ]);
2010-05-25 09:50:59 +02:00
2009-05-03 22:45:34 +02:00
// scroll to end of path
2012-10-31 19:00:28 +01:00
$GLOBALS [ 'egw' ] -> js -> set_onload ( " var p = document.getElementById('exec[path][c " . ( count ( explode ( '/' , $content [ 'path' ])) - 1 ) . " ]'); if (p) p.scrollIntoView(); " );
2009-05-11 22:43:18 +02:00
2009-04-15 23:11:57 +02:00
//_debug_array($readonlys);
egw_session :: appsession ( 'select_path' , 'filemanger' , $content [ 'path' ]);
2010-05-25 09:50:59 +02:00
$preserve = array (
2009-04-15 23:11:57 +02:00
'mode' => $content [ 'mode' ],
'method' => $content [ 'method' ],
'id' => $content [ 'id' ],
'label' => $content [ 'label' ],
2009-04-17 08:28:19 +02:00
'mime' => $content [ 'mime' ],
2013-10-04 11:28:10 +02:00
'options-mime' => $sel_options [ 'mime' ],
2012-10-31 19:20:34 +01:00
'old_path' => $content [ 'path' ],
2010-05-25 09:50:59 +02:00
);
if ( isset ( $content [ 'ckeditorfuncnum' ]))
{
$preserve [ 'ckeditorfuncnum' ] = $content [ 'ckeditorfuncnum' ];
$preserve [ 'ckeditor' ] = $content [ 'ckeditor' ];
}
$tpl -> exec ( 'filemanager.filemanager_select.select' , $content , $sel_options , $readonlys , $preserve , 2 );
2009-04-15 23:11:57 +02:00
}
2009-04-17 09:37:12 +02:00
/**
* Get a list off all apps having an application directory in VFS
*
* @ return array
*/
static function get_apps ()
{
2009-05-11 22:43:18 +02:00
$apps = array ( false ); // index starting from 1
if ( isset ( $GLOBALS [ 'egw_info' ][ 'apps' ][ 'stylite' ])) $apps = array ( 'favorites' => lang ( 'Favorites' ));
$apps += egw_link :: app_list ( 'query' );
2009-04-17 09:37:12 +02:00
unset ( $apps [ 'mydms' ]); // they do NOT support adding files to VFS
unset ( $apps [ 'wiki' ]);
2012-01-06 11:21:27 +01:00
unset ( $apps [ 'home-accounts' ]);
unset ( $apps [ 'addressbook-email' ]);
2009-04-17 09:37:12 +02:00
return $apps ;
}
2009-04-15 23:11:57 +02:00
}