3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
22 * @subpackage webservice
23 * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 require_once("$CFG->libdir/externallib.php");
28 require_once("$CFG->libdir/filelib.php");
30 class moodle_file_external extends external_api {
33 * Returns description of get_files parameters
34 * @return external_function_parameters
36 public static function get_files_parameters() {
37 return new external_function_parameters(
39 'params' => new external_single_structure(array(
40 'contextid' => new external_value(PARAM_INT, 'context id'),
41 'itemid' => new external_value(PARAM_INT, 'associated id'),
42 'filearea' => new external_value(PARAM_TEXT, 'file area'),
43 'filepath' => new external_value(PARAM_RAW, 'file path'),
44 'filename' => new external_value(PARAM_TEXT, 'file name'),
52 * Return moodle files listing
53 * @param array $fileinfo
56 public static function get_files($fileinfo) {
57 global $CFG, $USER, $OUTPUT;
58 if (empty($fileinfo['itemid'])) {
59 $fileinfo['itemid'] = null;
61 if (empty($fileinfo['filename'])) {
62 $fileinfo['filename'] = null;
64 if (empty($fileinfo['filepath'])) {
65 $fileinfo['filepath'] = null;
67 if (empty($fileinfo['filearea'])) {
68 $fileinfo['filearea'] = null;
70 if (empty($fileinfo['contextid'])) {
71 $context = get_system_context();
73 $context = get_context_instance_by_id($fileinfo['contextid']);
76 $browser = get_file_browser();
79 $return['parents'] = array();
80 $return['files'] = array();
81 $file = $browser->get_file_info($context, null, null, null, null);
82 if ($file = $browser->get_file_info($context, $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename'])) {
83 $level = $file->get_parent();
85 $params = $level->get_params();
86 $params['filename'] = $level->get_visible_name();
87 array_unshift($return['parents'], $params);
88 $level = $level->get_parent();
91 $children = $file->get_children();
92 foreach ($children as $child) {
93 $params = $child->get_params();
94 if ($child->is_directory()) {
96 'filename' => $child->get_visible_name(),
97 'filepath' => $params['filepath'],
98 'filearea' => $params['filearea'],
99 'itemid' => $params['itemid'],
100 'contextid' => $params['contextid'],
107 'filename' => $child->get_visible_name(),
108 'filepath' => $params['filepath'],
109 'filearea' => $params['filearea'],
110 'itemid' => $params['itemid'],
111 'contextid' => $params['contextid'],
112 'url' => $child->get_url(),
119 $return['files'] = $list;
120 } catch (Exception $e) {
127 * Returns description of get_files returns
128 * @return external_multiple_structure
130 public static function get_files_returns() {
131 return new external_single_structure(
133 'parents' => new external_multiple_structure(
134 new external_single_structure(
136 'contextid' => new external_value(PARAM_INT, ''),
137 'filename' => new external_value(PARAM_TEXT, ''),
138 'filearea' => new external_value(PARAM_TEXT, ''),
139 'filepath' => new external_value(PARAM_TEXT, ''),
140 'itemid' => new external_value(PARAM_INT, '')
144 'files' => new external_multiple_structure(
145 new external_single_structure(
147 'filename' => new external_value(PARAM_TEXT, ''),
148 'filearea' => new external_value(PARAM_TEXT, ''),
149 'filepath' => new external_value(PARAM_TEXT, ''),
150 'itemid' => new external_value(PARAM_INT, ''),
151 'isdir' => new external_value(PARAM_BOOL, ''),
152 'url' => new external_value(PARAM_TEXT, ''),
153 'contextid' => new external_value(PARAM_INT, '')
162 * Returns description of upload parameters
163 * @return external_function_parameters
165 public static function upload_parameters() {
166 return new external_function_parameters(
168 'params' => new external_single_structure(array(
169 'contextid' => new external_value(PARAM_INT, 'context id'),
170 'itemid' => new external_value(PARAM_INT, 'associated id'),
171 'filearea' => new external_value(PARAM_TEXT, 'file area'),
172 'filepath' => new external_value(PARAM_RAW, 'file path'),
173 'filename' => new external_value(PARAM_TEXT, 'file name'),
174 'filecontent' => new external_value(PARAM_TEXT, 'file content')
182 * Uploading a file to moodle
184 * @param array $fileinfo
187 public static function upload($fileinfo) {
191 if (!isset($fileinfo['filecontent'])) {
192 throw new moodle_exception('nofile');
195 if (!file_exists($CFG->dataroot.'/temp/wsupload')) {
196 mkdir($CFG->dataroot.'/temp/wsupload/', 0777, true);
199 if (is_dir($CFG->dataroot.'/temp/wsupload')) {
200 $dir = $CFG->dataroot.'/temp/wsupload/';
203 if (empty($fileinfo['filename'])) {
204 $filename = uniqid('wsupload').'_'.time().'.tmp';
206 $filename = $fileinfo['filename'];
209 if (file_exists($dir.$filename)) {
210 $filename = uniqid('m').$filename;
213 $savedfilepath = $dir.$filename;
215 file_put_contents($savedfilepath, base64_decode($fileinfo['filecontent']));
216 unset($fileinfo['filecontent']);
218 if (!empty($fileinfo['filearea'])) {
219 $filearea = $fileinfo['filearea'];
224 if (!empty($fileinfo['filepath'])) {
225 $filepath = $fileinfo['filepath'];
230 if (isset($fileinfo['itemid'])) {
231 $itemid = $fileinfo['itemid'];
233 $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100);
235 if (!empty($fileinfo['contextid'])) {
236 $context = get_context_instance_by_id($fileinfo['contextid']);
238 $context = get_system_context();
241 $fs = get_file_storage();
242 $browser = get_file_browser();
244 // check existing file
245 if ($file = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
246 throw new moodle_exception('fileexist');
249 $file_record = new object();
250 $file_record->contextid = $context->id;
251 $file_record->filearea = $filearea;
252 $file_record->itemid = $itemid;
253 $file_record->filepath = $filepath;
254 $file_record->filename = $filename;
255 $file_record->userid = $USER->id;
257 // move file to filepool
259 $file = $fs->create_file_from_pathname($file_record, $savedfilepath);
260 unlink($savedfilepath);
261 } catch (Exception $ex) {
264 $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
267 'filename'=>$file->get_filename(),
268 'filepath'=>$file->get_filepath(),
269 'filearea'=>$file->get_filearea(),
270 'url'=>$info->get_url()
275 * Returns description of upload returns
276 * @return external_multiple_structure
278 public static function upload_returns() {
279 return new external_single_structure(
281 'filename' => new external_value(PARAM_TEXT, ''),
282 'filepath' => new external_value(PARAM_TEXT, ''),
283 'filearea' => new external_value(PARAM_TEXT, ''),
284 'url' => new external_value(PARAM_TEXT, ''),