See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * Draft file ajax file manager 20 * 21 * @package core 22 * @subpackage repository 23 * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 define('AJAX_SCRIPT', true); 28 29 require('../config.php'); 30 require_once($CFG->libdir.'/filelib.php'); 31 require_once($CFG->libdir.'/adminlib.php'); 32 require_once($CFG->dirroot.'/repository/lib.php'); 33 $PAGE->set_context(context_system::instance()); 34 require_login(); 35 if (isguestuser()) { 36 throw new \moodle_exception('noguest'); 37 } 38 require_sesskey(); 39 40 $action = required_param('action', PARAM_ALPHA); 41 $draftid = required_param('itemid', PARAM_INT); 42 $filepath = optional_param('filepath', '/', PARAM_PATH); 43 44 $usercontext = context_user::instance($USER->id); 45 46 echo $OUTPUT->header(); // send headers 47 48 // 49 //NOTE TO ALL DEVELOPERS: this script must deal only with draft area of current user, it has to use only file_storage and no file_browser!! 50 // 51 52 switch ($action) { 53 case 'dir': 54 $data = new stdClass(); 55 file_get_drafarea_folders($draftid, $filepath, $data); 56 echo json_encode($data); 57 die; 58 59 case 'list': 60 $filepath = optional_param('filepath', '/', PARAM_PATH); 61 62 $data = repository::prepare_listing(file_get_drafarea_files($draftid, $filepath)); 63 $info = file_get_draft_area_info($draftid); 64 $data->filecount = $info['filecount']; 65 $data->filesize = $info['filesize']; 66 $data->tree = new stdClass(); 67 file_get_drafarea_folders($draftid, '/', $data->tree); 68 echo json_encode($data); 69 die; 70 71 case 'mkdir': 72 $filepath = required_param('filepath', PARAM_PATH); 73 $newdirname = required_param('newdirname', PARAM_FILE); 74 75 $fs = get_file_storage(); 76 $fs->create_directory($usercontext->id, 'user', 'draft', $draftid, file_correct_filepath(file_correct_filepath($filepath).$newdirname)); 77 $return = new stdClass(); 78 $return->filepath = $filepath; 79 echo json_encode($return); 80 die; 81 82 case 'delete': 83 $filename = required_param('filename', PARAM_FILE); 84 $filepath = required_param('filepath', PARAM_PATH); 85 $selectedfile = (object)[ 86 'filename' => $filename, 87 'filepath' => $filepath 88 ]; 89 $return = repository_delete_selected_files($usercontext, 'user', 'draft', $draftid, [$selectedfile]); 90 91 if ($return) { 92 $response = new stdClass(); 93 $response->filepath = array_keys($return)[0]; 94 echo json_encode($response); 95 die; 96 } 97 98 echo json_encode(false); 99 die; 100 101 case 'deleteselected': 102 $selected = required_param('selected', PARAM_RAW); 103 $return = []; 104 $selectedfiles = json_decode($selected); 105 $return = repository_delete_selected_files($usercontext, 'user', 'draft', $draftid, $selectedfiles); 106 echo (json_encode($return ? array_keys($return) : false)); 107 die; 108 109 case 'setmainfile': 110 $filename = required_param('filename', PARAM_FILE); 111 $filepath = required_param('filepath', PARAM_PATH); 112 113 $filepath = file_correct_filepath($filepath); 114 // reset sort order 115 file_reset_sortorder($usercontext->id, 'user', 'draft', $draftid); 116 // set main file 117 $return = file_set_sortorder($usercontext->id, 'user', 'draft', $draftid, $filepath, $filename, 1); 118 echo json_encode($return); 119 die; 120 121 case 'updatefile': 122 // Allows to Rename file, move it to another directory, change it's license and author information in one request 123 $filename = required_param('filename', PARAM_FILE); 124 $filepath = required_param('filepath', PARAM_PATH); 125 $updatedata = array(); 126 $updatedata['filename'] = optional_param('newfilename', $filename, PARAM_FILE); 127 $updatedata['filepath'] = $newfilepath = optional_param('newfilepath', $filepath, PARAM_PATH); 128 if (($v = optional_param('newlicense', false, PARAM_TEXT)) !== false) { 129 $updatedata['license'] = $v; 130 } 131 if (($v = optional_param('newauthor', false, PARAM_TEXT)) !== false) { 132 $updatedata['author'] = $v; 133 } 134 try { 135 repository::update_draftfile($draftid, $filepath, $filename, $updatedata); 136 } catch (moodle_exception $e) { 137 die(json_encode((object)array('error' => $e->getMessage()))); 138 } 139 die(json_encode((object)array('filepath' => $newfilepath))); 140 141 case 'updatedir': 142 $filepath = required_param('filepath', PARAM_PATH); 143 $newdirname = required_param('newdirname', PARAM_FILE); 144 $parent = required_param('newfilepath', PARAM_PATH); 145 $newfilepath = clean_param($parent . '/' . $newdirname . '/', PARAM_PATH); 146 try { 147 repository::update_draftfile($draftid, $filepath, '.', array('filepath' => $newfilepath)); 148 } catch (moodle_exception $e) { 149 die(json_encode((object)array('error' => $e->getMessage()))); 150 } 151 die(json_encode((object)array('filepath' => $parent))); 152 153 case 'zip': 154 $filepath = required_param('filepath', PARAM_PATH); 155 156 $zipper = get_file_packer('application/zip'); 157 $fs = get_file_storage(); 158 159 $file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, '.'); 160 161 $parent_path = $file->get_parent_directory()->get_filepath(); 162 163 $filepath = explode('/', trim($file->get_filepath(), '/')); 164 $filepath = array_pop($filepath); 165 $zipfile = repository::get_unused_filename($draftid, $parent_path, $filepath . '.zip'); 166 167 if ($newfile = $zipper->archive_to_storage([$filepath => $file], $usercontext->id, 'user', 'draft', $draftid, $parent_path, $zipfile, $USER->id)) { 168 $return = new stdClass(); 169 $return->filepath = $parent_path; 170 echo json_encode($return); 171 } else { 172 echo json_encode(false); 173 } 174 die; 175 case 'downloadselected': 176 $selected = required_param('selected', PARAM_RAW); 177 $selectedfiles = json_decode($selected); 178 if (!count($selectedfiles)) { 179 $filepath = required_param('filepath', PARAM_PATH); 180 $selectedfiles = [(object)[ 181 'filename' => '', 182 'filepath' => $filepath 183 ]]; 184 } 185 $return = repository_download_selected_files($usercontext, 'user', 'draft', $draftid, $selectedfiles); 186 echo (json_encode($return)); 187 die; 188 189 case 'downloaddir': 190 $filepath = required_param('filepath', PARAM_PATH); 191 192 $selectedfile = (object)[ 193 'filename' => '', 194 'filepath' => $filepath 195 ]; 196 $return = repository_download_selected_files($usercontext, 'user', 'draft', $draftid, [$selectedfile]); 197 echo json_encode($return); 198 die; 199 200 case 'unzip': 201 $filename = required_param('filename', PARAM_FILE); 202 $filepath = required_param('filepath', PARAM_PATH); 203 $areamaxbytes = required_param('areamaxbytes', PARAM_INT); 204 205 $return = new stdClass(); 206 $zipper = get_file_packer('application/zip'); 207 $fs = get_file_storage(); 208 $file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, $filename); 209 // Get the total size of the content in the archive. 210 $filecontentsize = $file->get_total_content_size($zipper); 211 212 // Return an error if the returned size of the content is NULL. 213 // This means the utility class was unable to read the content of the archive. 214 if (is_null($filecontentsize)) { 215 $return->error = get_string('cannotunzipcontentunreadable', 'repository'); 216 die(json_encode($return)); 217 } 218 219 // Check whether the maximum size allowed in this draft area will be exceeded with unzipping the file. 220 // If the maximum size allowed is exceeded, return an error before attempting to unzip. 221 if (file_is_draft_area_limit_reached($draftid, $areamaxbytes, $filecontentsize)) { 222 $return->error = get_string('cannotunzipquotaexceeded', 'repository'); 223 die(json_encode($return)); 224 } 225 226 // Find unused name for directory to extract the archive. 227 $temppath = $fs->get_unused_dirname($usercontext->id, 'user', 'draft', $draftid, $filepath. pathinfo($filename, PATHINFO_FILENAME). '/'); 228 $donotremovedirs = array(); 229 $doremovedirs = array($temppath); 230 231 // Extract archive and move all files from $temppath to $filepath 232 if (($processed = $file->extract_to_storage($zipper, $usercontext->id, 'user', 'draft', $draftid, $temppath, $USER->id)) 233 !== false) { 234 235 // Find all failures within the processed files, and return an error if any are found. 236 $failed = array_filter($processed, static function($result): bool { 237 return $result !== true; 238 }); 239 if (count($failed) > 0) { 240 $return->error = get_string('cannotunzipextractfileerror', 'repository'); 241 die(json_encode($return)); 242 } 243 244 $extractedfiles = $fs->get_directory_files($usercontext->id, 'user', 'draft', $draftid, $temppath, true); 245 $xtemppath = preg_quote($temppath, '|'); 246 foreach ($extractedfiles as $file) { 247 $realpath = preg_replace('|^'.$xtemppath.'|', $filepath, $file->get_filepath()); 248 if (!$file->is_directory()) { 249 // Set the source to the extracted file to indicate that it came from archive. 250 $file->set_source(serialize((object)array('source' => $filepath))); 251 } 252 if (!$fs->file_exists($usercontext->id, 'user', 'draft', $draftid, $realpath, $file->get_filename())) { 253 // File or directory did not exist, just move it. 254 $file->rename($realpath, $file->get_filename()); 255 } else if (!$file->is_directory()) { 256 // File already existed, overwrite it 257 repository::overwrite_existing_draftfile($draftid, $realpath, $file->get_filename(), $file->get_filepath(), $file->get_filename()); 258 } else { 259 // Directory already existed, remove temporary dir but make sure we don't remove the existing dir 260 $doremovedirs[] = $file->get_filepath(); 261 $donotremovedirs[] = $realpath; 262 } 263 } 264 $return->filepath = $filepath; 265 } else { 266 $return = false; 267 } 268 // Remove remaining temporary directories. 269 foreach (array_diff($doremovedirs, $donotremovedirs) as $filepath) { 270 if ($file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, '.')) { 271 $file->delete(); 272 } 273 } 274 die(json_encode($return)); 275 276 case 'getoriginal': 277 $filename = required_param('filename', PARAM_FILE); 278 $filepath = required_param('filepath', PARAM_PATH); 279 280 $fs = get_file_storage(); 281 $file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, $filename); 282 if (!$file) { 283 echo json_encode(false); 284 } else { 285 $return = array('filename' => $filename, 'filepath' => $filepath, 'original' => $file->get_reference_details()); 286 echo json_encode((object)$return); 287 } 288 die; 289 290 case 'getreferences': 291 $filename = required_param('filename', PARAM_FILE); 292 $filepath = required_param('filepath', PARAM_PATH); 293 294 $fs = get_file_storage(); 295 $file = $fs->get_file($usercontext->id, 'user', 'draft', $draftid, $filepath, $filename); 296 if (!$file) { 297 echo json_encode(false); 298 } else { 299 $source = unserialize($file->get_source()); 300 $return = array('filename' => $filename, 'filepath' => $filepath, 'references' => array()); 301 $browser = get_file_browser(); 302 if (isset($source->original)) { 303 $reffiles = $fs->search_references($source->original); 304 foreach ($reffiles as $reffile) { 305 $refcontext = context::instance_by_id($reffile->get_contextid()); 306 $fileinfo = $browser->get_file_info($refcontext, $reffile->get_component(), $reffile->get_filearea(), $reffile->get_itemid(), $reffile->get_filepath(), $reffile->get_filename()); 307 if (empty($fileinfo)) { 308 $return['references'][] = get_string('undisclosedreference', 'repository'); 309 } else { 310 $return['references'][] = $fileinfo->get_readable_fullname(); 311 } 312 } 313 } 314 echo json_encode((object)$return); 315 } 316 die; 317 318 default: 319 // no/unknown action? 320 echo json_encode(false); 321 die; 322 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body