1<?php 2/** 3 * EGroupware - Filemanager - select file to open or save dialog 4 * 5 * @link http://www.egroupware.org 6 * @package filemanager 7 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> 8 * @copyright (c) 2009-2016 by Ralf Becker <RalfBecker-AT-outdoor-training.de> 9 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License 10 * @version $Id$ 11 */ 12 13use EGroupware\Api; 14use EGroupware\Api\Link; 15use EGroupware\Api\Framework; 16use EGroupware\Api\Egw; 17use EGroupware\Api\Vfs; 18use EGroupware\Api\Etemplate; 19 20/** 21 * Select file to open or save dialog 22 * 23 * This dialog can be called from applications to open or store files from the VFS. 24 * 25 * There are the following ($_GET) parameters: 26 * - menuaction=filemanager.filemanager_select.select (required) 27 * - mode=(open|open-multiple|saveas|select-dir) (required) 28 * - method=app.class.method (required callback, gets called with id and selected file(s)) 29 * - id=... (optional parameter passed to callback) 30 * - path=... (optional start path in VFS) 31 * - mime=... (optional mime-type to limit display to given type) 32 * - label=... (optional label for submit button, default "Open") 33 * 34 * The application calls this method in a popup with size: 640x580 px 35 * After the user selected one or more files (depending on the mode parameter), the "method" callback gets 36 * called on server (!) side. Parameters are the id plus the selected files as 1. and 2. parameter. 37 * The callback returns javascript to eg. update it's UI AND (!) to close the current popup ("window.close();"). 38 * 39 * @deprecated This class is deprecated in favor of et2_vfsSelect widget. Please 40 * use et2_vfsSelect widget if you are not running old etemplate. 41 * 42 * @todo this class should be removed once we have all applications ported in et2 43 */ 44class filemanager_select 45{ 46 /** 47 * Methods callable via menuaction 48 * 49 * @var array 50 */ 51 var $public_functions = array( 52 'select' => true, 53 ); 54 55 /** 56 * Constructor 57 * 58 */ 59 function __construct() 60 { 61 // strip slashes from _GET parameters, if someone still has magic_quotes_gpc on 62 if (get_magic_quotes_gpc() && $_GET) 63 { 64 $_GET = array_stripslashes($_GET); 65 } 66 } 67 68 /** 69 * File selector 70 * 71 * @param array $content 72 * 73 * @deprecated Please use et2_vfsSelect widget in client side instead 74 */ 75 function select(array $content=null) 76 { 77 if (!is_array($content)) 78 { 79 $content = array(); 80 $content['mode'] = $_GET['mode']; 81 if (!in_array($content['mode'],array('open','open-multiple','saveas','select-dir'))) 82 { 83 throw new Api\Exception\WrongParameter("Wrong or unset required mode parameter!"); 84 } 85 $content['path'] = $_GET['path']; 86 if (empty($content['path'])) 87 { 88 $content['path'] = Api\Cache::getSession('filemanger', 'select_path'); 89 } 90 $content['name'] = (string)$_GET['name']; 91 $content['method'] = $_GET['method']; 92 $content['id'] = $_GET['id']; 93 $content['label'] = isset($_GET['label']) ? $_GET['label'] : lang('Open'); 94 if (($content['options-mime'] = isset($_GET['mime']))) 95 { 96 $sel_options['mime'] = array(); 97 foreach((array)$_GET['mime'] as $key => $value) 98 { 99 if (is_numeric($key)) 100 { 101 $sel_options['mime'][$value] = lang('%1 files',strtoupper(Api\MimeMagic::mime2ext($value))).' ('.$value.')'; 102 } 103 else 104 { 105 $sel_options['mime'][$key] = lang('%1 files',strtoupper($value)).' ('.$key.')'; 106 } 107 } 108 109 $content['mime'] = key($sel_options['mime']); 110 error_log(array2string($content['options-mime'])); 111 } 112 } 113 elseif(isset($content['button'])) 114 { 115 $button = key($content['button']); 116 unset($content['button']); 117 switch($button) 118 { 119 case 'home': 120 $content['path'] = filemanager_ui::get_home_dir(); 121 break; 122 case 'ok': 123 $copy_result = null; 124 if (isset($content['file_upload']['name']) && file_exists($content['file_upload']['tmp_name'])) 125 { 126 //Set the "content" name filed accordingly to the uploaded file 127 // encode chars which special meaning in url/vfs (some like / get removed!) 128 $content['name'] = Vfs::encodePathComponent($content['file_upload']['name']); 129 $to_path = Vfs::concat($content['path'],$content['name']); 130 131 $copy_result = (Vfs::is_writable($content['path']) || Vfs::is_writable($to_path)) && 132 copy($content['file_upload']['tmp_name'],Vfs::PREFIX.$to_path); 133 } 134 135 //Break on an error condition 136 if ((($content['mode'] == 'open' || $content['mode'] == 'saveas') && ($content['name'] == '')) || ($copy_result === false)) 137 { 138 if ($copy_result === false) 139 { 140 $content['msg'] = lang('Error uploading file!'); 141 } 142 else 143 { 144 $content['msg'] = lang('Filename must not be empty!'); 145 } 146 $content['name'] = ''; 147 148 break; 149 } 150 151 switch($content['mode']) 152 { 153 case 'open-multiple': 154 foreach((array)$content['dir']['selected'] as $name) 155 { 156 $files[] = Vfs::concat($content['path'],$name); 157 } 158 //Add an uploaded file to the files result array2string 159 if ($copy_result === true) $files[] = $to_path; 160 break; 161 162 case 'select-dir': 163 $files = $content['path']; 164 break; 165 166 case 'saveas': 167 // Don't trust the name the user gives, encode it 168 $content['name'] = Vfs::encodePathComponent($content['name']); 169 // Fall through 170 171 default: 172 $files = Vfs::concat($content['path'],$content['name']); 173 break; 174 } 175 176 if ($content['method'] == 'download_url' && !is_array($files)) 177 { 178 $files = Vfs::download_url($files); 179 if ($files[0] == '/') $files = Egw::link($files); 180 } 181 else 182 { 183 $js = ExecMethod2($content['method'],$content['id'],$files); 184 } 185 186 if(Api\Json\Response::isJSONResponse()) 187 { 188 $response = Api\Json\Response::get(); 189 if($js) 190 { 191 $response->script($js); 192 } 193 // Ahh! 194 // The vfs-select widget looks for this 195 $response->script('this.selected_files = '.json_encode($files) . ';'); 196 Framework::window_close(); 197 } 198 else 199 { 200 header('Content-type: text/html; charset='.Api\Translation::charset()); 201 echo "<html>\n<head>\n<script type='text/javascript'>\n$js\n</script>\n</head>\n</html>\n"; 202 } 203 exit(); 204 } 205 206 $sel_options['mime'] = $content['options-mime']; 207 } 208 elseif(isset($content['apps'])) 209 { 210 $app = key($content['apps']); 211 if ($app == 'home') $content['path'] = filemanager_ui::get_home_dir(); 212 } 213 214 //Deactivate the opload field if the current directory is not writeable or 215 //we're currently not in the single file open mode. 216 $content['no_upload'] = !Vfs::is_writable($content['path']) || 217 !in_array($content['mode'],array('open')); 218 219 $content['apps'] = array_keys(self::get_apps()); 220 221 if (isset($app)) 222 { 223 $content['path'] = '/apps/'.(isset($content['apps'][$app]) ? $content['apps'][$app] : $app); 224 } 225 226 // Set a flag for easy detection as we go 227 $favorites_flag = substr($content['path'],0,strlen('/apps/favorites')) == '/apps/favorites'; 228 229 if (!$favorites_flag && (!$content['path'] || !Vfs::is_dir($content['path']))) 230 { 231 $content['path'] = filemanager_ui::get_home_dir(); 232 } 233 $tpl = new Etemplate('filemanager.select'); 234 235 if ($favorites_flag) 236 { 237 // Display favorites as if they were folders 238 $files = array(); 239 $favorites = Framework\Favorites::get_favorites('filemanager'); 240 $n = 0; 241 foreach($favorites as $favorite) 242 { 243 $path = $favorite['state']['path']; 244 // Just directories 245 if(!$path) continue; 246 if ($path == $content['path']) continue; // remove directory itself 247 248 $mime = Vfs::mime_content_type($path); 249 $content['dir'][$n] = array( 250 'name' => $favorite['name'], 251 'path' => $path, 252 'mime' => $mime, 253 'is_dir' => true 254 ); 255 if ($content['mode'] == 'open-multiple') 256 { 257 $readonlys['selected['.$favorite['name'].']'] = true; 258 } 259 ++$n; 260 } 261 } 262 else if (!($files = Vfs::find($content['path'],array( 263 'dirsontop' => true, 264 'order' => 'name', 265 'sort' => 'ASC', 266 'maxdepth' => 1, 267 )))) 268 { 269 $content['msg'] = lang("Can't open directory %1!",$content['path']); 270 } 271 else 272 { 273 $n = 0; 274 $content['dir'] = array('mode' => $content['mode']); 275 foreach($files as $path) 276 { 277 if ($path == $content['path']) continue; // remove directory itself 278 279 $name = Vfs::basename($path); 280 $is_dir = Vfs::is_dir($path); 281 $mime = Vfs::mime_content_type($path); 282 if ($content['mime'] && !$is_dir && $mime != $content['mime']) 283 { 284 continue; // does not match mime-filter --> ignore 285 } 286 $content['dir'][$n] = array( 287 'name' => $name, 288 'path' => $path, 289 'mime' => $mime, 290 'is_dir' => $is_dir 291 ); 292 if ($is_dir && $content['mode'] == 'open-multiple') 293 { 294 $readonlys['selected['.$name.']'] = true; 295 } 296 ++$n; 297 } 298 if (!$n) $readonlys['selected[]'] = true; // remove checkbox from empty line 299 } 300 $readonlys['button[createdir]'] = !Vfs::is_writable($content['path']); 301 302 //_debug_array($readonlys); 303 Api\Cache::setSession('filemanger', 'select_path', $content['path']); 304 $preserve = array( 305 'mode' => $content['mode'], 306 'method' => $content['method'], 307 'id' => $content['id'], 308 'label' => $content['label'], 309 'mime' => $content['mime'], 310 'options-mime' => $sel_options['mime'], 311 'old_path' => $content['path'], 312 ); 313 $tpl->exec('filemanager.filemanager_select.select',$content,$sel_options,$readonlys,$preserve,2); 314 } 315 316 /** 317 * Get a list off all apps having an application directory in VFS 318 * 319 * @return array 320 */ 321 static function get_apps() 322 { 323 $apps = array(false); // index starting from 1 324 if (isset($GLOBALS['egw_info']['apps']['stylite'])) $apps = array('favorites' => lang('Favorites')); 325 $apps += Link::app_list('query'); 326 327 unset($apps['mydms']); // they do NOT support adding files to VFS 328 unset($apps['wiki']); 329 unset($apps['api-accounts']); 330 unset($apps['addressbook-email']); 331 332 return $apps; 333 } 334} 335