See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 18 /** 19 * External files API 20 * 21 * @package core_files 22 * @category external 23 * @copyright 2010 Dongsheng Cai 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once("$CFG->libdir/externallib.php"); 30 require_once("$CFG->libdir/filelib.php"); 31 32 /** 33 * Files external functions 34 * 35 * @package core_files 36 * @category external 37 * @copyright 2011 Jerome Mouneyrac 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 * @since Moodle 2.2 40 */ 41 class core_files_external extends external_api { 42 43 /** 44 * Returns description of get_files parameters 45 * 46 * @return external_function_parameters 47 * @since Moodle 2.2 48 */ 49 public static function get_files_parameters() { 50 return new external_function_parameters( 51 array( 52 'contextid' => new external_value(PARAM_INT, 'context id Set to -1 to use contextlevel and instanceid.'), 53 'component' => new external_value(PARAM_TEXT, 'component'), 54 'filearea' => new external_value(PARAM_TEXT, 'file area'), 55 'itemid' => new external_value(PARAM_INT, 'associated id'), 56 'filepath' => new external_value(PARAM_PATH, 'file path'), 57 'filename' => new external_value(PARAM_TEXT, 'file name'), 58 'modified' => new external_value(PARAM_INT, 'timestamp to return files changed after this time.', VALUE_DEFAULT, null), 59 'contextlevel' => new external_value(PARAM_ALPHA, 'The context level for the file location.', VALUE_DEFAULT, null), 60 'instanceid' => new external_value(PARAM_INT, 'The instance id for where the file is located.', VALUE_DEFAULT, null) 61 62 ) 63 ); 64 } 65 66 /** 67 * Return moodle files listing 68 * 69 * @param int $contextid context id 70 * @param int $component component 71 * @param int $filearea file area 72 * @param int $itemid item id 73 * @param string $filepath file path 74 * @param string $filename file name 75 * @param int $modified timestamp to return files changed after this time. 76 * @param string $contextlevel The context level for the file location. 77 * @param int $instanceid The instance id for where the file is located. 78 * @return array 79 * @since Moodle 2.9 Returns additional fields (timecreated, filesize, author, license) 80 * @since Moodle 2.2 81 */ 82 public static function get_files($contextid, $component, $filearea, $itemid, $filepath, $filename, $modified = null, 83 $contextlevel = null, $instanceid = null) { 84 85 $parameters = array( 86 'contextid' => $contextid, 87 'component' => $component, 88 'filearea' => $filearea, 89 'itemid' => $itemid, 90 'filepath' => $filepath, 91 'filename' => $filename, 92 'modified' => $modified, 93 'contextlevel' => $contextlevel, 94 'instanceid' => $instanceid); 95 $fileinfo = self::validate_parameters(self::get_files_parameters(), $parameters); 96 97 $browser = get_file_browser(); 98 99 // We need to preserve backwards compatibility. Zero will use the system context and minus one will 100 // use the addtional parameters to determine the context. 101 // TODO MDL-40489 get_context_from_params should handle this logic. 102 if ($fileinfo['contextid'] == 0) { 103 $context = context_system::instance(); 104 } else { 105 if ($fileinfo['contextid'] == -1) { 106 $fileinfo['contextid'] = null; 107 } 108 $context = self::get_context_from_params($fileinfo); 109 } 110 self::validate_context($context); 111 112 if (empty($fileinfo['component'])) { 113 $fileinfo['component'] = null; 114 } 115 if (empty($fileinfo['filearea'])) { 116 $fileinfo['filearea'] = null; 117 } 118 if (empty($fileinfo['filename'])) { 119 $fileinfo['filename'] = null; 120 } 121 if (empty($fileinfo['filepath'])) { 122 $fileinfo['filepath'] = null; 123 } 124 125 $return = array(); 126 $return['parents'] = array(); 127 $return['files'] = array(); 128 $list = array(); 129 130 if ($file = $browser->get_file_info( 131 $context, $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], 132 $fileinfo['filepath'], $fileinfo['filename'])) { 133 $level = $file->get_parent(); 134 while ($level) { 135 $params = $level->get_params(); 136 $params['filename'] = $level->get_visible_name(); 137 array_unshift($return['parents'], $params); 138 $level = $level->get_parent(); 139 } 140 $children = $file->get_children(); 141 foreach ($children as $child) { 142 143 $params = $child->get_params(); 144 $timemodified = $child->get_timemodified(); 145 $timecreated = $child->get_timecreated(); 146 147 if ($child->is_directory()) { 148 if ((is_null($modified)) or ($modified < $timemodified)) { 149 $node = array( 150 'contextid' => $params['contextid'], 151 'component' => $params['component'], 152 'filearea' => $params['filearea'], 153 'itemid' => $params['itemid'], 154 'filepath' => $params['filepath'], 155 'filename' => $child->get_visible_name(), 156 'url' => null, 157 'isdir' => true, 158 'timemodified' => $timemodified, 159 'timecreated' => $timecreated, 160 'filesize' => 0, 161 'author' => null, 162 'license' => null 163 ); 164 $list[] = $node; 165 } 166 } else { 167 if ((is_null($modified)) or ($modified < $timemodified)) { 168 $node = array( 169 'contextid' => $params['contextid'], 170 'component' => $params['component'], 171 'filearea' => $params['filearea'], 172 'itemid' => $params['itemid'], 173 'filepath' => $params['filepath'], 174 'filename' => $child->get_visible_name(), 175 'url' => $child->get_url(), 176 'isdir' => false, 177 'timemodified' => $timemodified, 178 'timecreated' => $timecreated, 179 'filesize' => $child->get_filesize(), 180 'author' => $child->get_author(), 181 'license' => $child->get_license() 182 ); 183 $list[] = $node; 184 } 185 } 186 } 187 } 188 $return['files'] = $list; 189 return $return; 190 } 191 192 /** 193 * Returns description of get_files returns 194 * 195 * @return external_single_structure 196 * @since Moodle 2.9 Returns additional fields for files (timecreated, filesize, author, license) 197 * @since Moodle 2.2 198 */ 199 public static function get_files_returns() { 200 return new external_single_structure( 201 array( 202 'parents' => new external_multiple_structure( 203 new external_single_structure( 204 array( 205 'contextid' => new external_value(PARAM_INT, ''), 206 'component' => new external_value(PARAM_COMPONENT, ''), 207 'filearea' => new external_value(PARAM_AREA, ''), 208 'itemid' => new external_value(PARAM_INT, ''), 209 'filepath' => new external_value(PARAM_TEXT, ''), 210 'filename' => new external_value(PARAM_TEXT, ''), 211 ) 212 ) 213 ), 214 'files' => new external_multiple_structure( 215 new external_single_structure( 216 array( 217 'contextid' => new external_value(PARAM_INT, ''), 218 'component' => new external_value(PARAM_COMPONENT, ''), 219 'filearea' => new external_value(PARAM_AREA, ''), 220 'itemid' => new external_value(PARAM_INT, ''), 221 'filepath' => new external_value(PARAM_TEXT, ''), 222 'filename' => new external_value(PARAM_TEXT, ''), 223 'isdir' => new external_value(PARAM_BOOL, ''), 224 'url' => new external_value(PARAM_TEXT, ''), 225 'timemodified' => new external_value(PARAM_INT, ''), 226 'timecreated' => new external_value(PARAM_INT, 'Time created', VALUE_OPTIONAL), 227 'filesize' => new external_value(PARAM_INT, 'File size', VALUE_OPTIONAL), 228 'author' => new external_value(PARAM_TEXT, 'File owner', VALUE_OPTIONAL), 229 'license' => new external_value(PARAM_TEXT, 'File license', VALUE_OPTIONAL), 230 ) 231 ) 232 ) 233 ) 234 ); 235 } 236 237 /** 238 * Returns description of upload parameters 239 * 240 * @return external_function_parameters 241 * @since Moodle 2.2 242 */ 243 public static function upload_parameters() { 244 return new external_function_parameters( 245 array( 246 'contextid' => new external_value(PARAM_INT, 'context id', VALUE_DEFAULT, null), 247 'component' => new external_value(PARAM_COMPONENT, 'component'), 248 'filearea' => new external_value(PARAM_AREA, 'file area'), 249 'itemid' => new external_value(PARAM_INT, 'associated id'), 250 'filepath' => new external_value(PARAM_PATH, 'file path'), 251 'filename' => new external_value(PARAM_FILE, 'file name'), 252 'filecontent' => new external_value(PARAM_TEXT, 'file content'), 253 'contextlevel' => new external_value(PARAM_ALPHA, 'The context level to put the file in, 254 (block, course, coursecat, system, user, module)', VALUE_DEFAULT, null), 255 'instanceid' => new external_value(PARAM_INT, 'The Instance id of item associated 256 with the context level', VALUE_DEFAULT, null) 257 ) 258 ); 259 } 260 261 /** 262 * Uploading a file to moodle 263 * 264 * @param int $contextid context id 265 * @param string $component component 266 * @param string $filearea file area 267 * @param int $itemid item id 268 * @param string $filepath file path 269 * @param string $filename file name 270 * @param string $filecontent file content 271 * @param string $contextlevel Context level (block, course, coursecat, system, user or module) 272 * @param int $instanceid Instance id of the item associated with the context level 273 * @return array 274 * @since Moodle 2.2 275 */ 276 public static function upload($contextid, $component, $filearea, $itemid, $filepath, $filename, $filecontent, $contextlevel, $instanceid) { 277 global $USER, $CFG; 278 279 $fileinfo = self::validate_parameters(self::upload_parameters(), array( 280 'contextid' => $contextid, 'component' => $component, 'filearea' => $filearea, 'itemid' => $itemid, 281 'filepath' => $filepath, 'filename' => $filename, 'filecontent' => $filecontent, 'contextlevel' => $contextlevel, 282 'instanceid' => $instanceid)); 283 284 if (!isset($fileinfo['filecontent'])) { 285 throw new moodle_exception('nofile'); 286 } 287 // Saving file. 288 $dir = make_temp_directory('wsupload'); 289 290 if (empty($fileinfo['filename'])) { 291 $filename = uniqid('wsupload', true).'_'.time().'.tmp'; 292 } else { 293 $filename = $fileinfo['filename']; 294 } 295 296 if (file_exists($dir.$filename)) { 297 $savedfilepath = $dir.uniqid('m').$filename; 298 } else { 299 $savedfilepath = $dir.$filename; 300 } 301 302 file_put_contents($savedfilepath, base64_decode($fileinfo['filecontent'])); 303 @chmod($savedfilepath, $CFG->filepermissions); 304 unset($fileinfo['filecontent']); 305 306 if (!empty($fileinfo['filepath'])) { 307 $filepath = $fileinfo['filepath']; 308 } else { 309 $filepath = '/'; 310 } 311 312 // Only allow uploads to draft area 313 if (!($fileinfo['component'] == 'user' and $fileinfo['filearea'] == 'draft')) { 314 throw new coding_exception('File can be uploaded to user draft area only'); 315 } else { 316 $component = 'user'; 317 $filearea = $fileinfo['filearea']; 318 } 319 320 $itemid = 0; 321 if (isset($fileinfo['itemid'])) { 322 $itemid = $fileinfo['itemid']; 323 } 324 if ($filearea == 'draft' && $itemid <= 0) { 325 // Generate a draft area for the files. 326 $itemid = file_get_unused_draft_itemid(); 327 } else if ($filearea == 'private') { 328 // TODO MDL-31116 in user private area, itemid is always 0. 329 $itemid = 0; 330 } 331 332 // We need to preserve backword compatibility. Context id is no more a required. 333 if (empty($fileinfo['contextid'])) { 334 unset($fileinfo['contextid']); 335 } 336 337 // Get and validate context. 338 $context = self::get_context_from_params($fileinfo); 339 self::validate_context($context); 340 if (($fileinfo['component'] == 'user' and $fileinfo['filearea'] == 'private')) { 341 throw new moodle_exception('privatefilesupload'); 342 } 343 344 $browser = get_file_browser(); 345 346 // Check existing file. 347 if ($file = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, $filename)) { 348 throw new moodle_exception('fileexist'); 349 } 350 351 // Move file to filepool. 352 if ($dir = $browser->get_file_info($context, $component, $filearea, $itemid, $filepath, '.')) { 353 $info = $dir->create_file_from_pathname($filename, $savedfilepath); 354 $params = $info->get_params(); 355 unlink($savedfilepath); 356 return array( 357 'contextid'=>$params['contextid'], 358 'component'=>$params['component'], 359 'filearea'=>$params['filearea'], 360 'itemid'=>$params['itemid'], 361 'filepath'=>$params['filepath'], 362 'filename'=>$params['filename'], 363 'url'=>$info->get_url() 364 ); 365 } else { 366 throw new moodle_exception('nofile'); 367 } 368 } 369 370 /** 371 * Returns description of upload returns 372 * 373 * @return external_single_structure 374 * @since Moodle 2.2 375 */ 376 public static function upload_returns() { 377 return new external_single_structure( 378 array( 379 'contextid' => new external_value(PARAM_INT, ''), 380 'component' => new external_value(PARAM_COMPONENT, ''), 381 'filearea' => new external_value(PARAM_AREA, ''), 382 'itemid' => new external_value(PARAM_INT, ''), 383 'filepath' => new external_value(PARAM_TEXT, ''), 384 'filename' => new external_value(PARAM_FILE, ''), 385 'url' => new external_value(PARAM_TEXT, ''), 386 ) 387 ); 388 } 389 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body