e1a488e00f417383430bc59f1de07744d808aac7
[moodle.git] / files / externallib.php
1 <?php
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/>.
18 /**
19  * External files API
20  *
21  * @package    moodlecore
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
25  */
27 require_once("$CFG->libdir/externallib.php");
28 require_once("$CFG->libdir/filelib.php");
30 class moodle_file_external extends external_api {
32     /**
33      * Returns description of get_files parameters
34      * @return external_function_parameters
35      */
36     public static function get_files_parameters() {
37         return new external_function_parameters(
38             array(
39                 'params' => new external_single_structure(array(
40                         'contextid' => new external_value(PARAM_INT, 'context id'),
41                         'component' => new external_value(PARAM_TEXT, 'component'),
42                         'filearea'  => new external_value(PARAM_TEXT, 'file area'),
43                         'itemid'    => new external_value(PARAM_INT, 'associated id'),
44                         'filepath'  => new external_value(PARAM_RAW, 'file path'),
45                         'filename'  => new external_value(PARAM_TEXT, 'file name'),
46                     )
47                 )
48             )
49         );
50     }
52     /**
53      * Return moodle files listing
54      * @param array $fileinfo
55      * @return array
56      */
57     public static function get_files($fileinfo) {
59 throw new coding_exception('File browsing api function is not implemented yet, sorry');
61         global $CFG, $USER, $OUTPUT;
62         if (empty($fileinfo['contextid'])) {
63             $context  = get_system_context();
64         } else {
65             $context  = get_context_instance_by_id($fileinfo['contextid']);
66         }
67         if (empty($fileinfo['component'])) {
68             $fileinfo['component'] = null;
69         }
70         if (empty($fileinfo['filearea'])) {
71             $fileinfo['filearea'] = null;
72         }
73         if (empty($fileinfo['itemid'])) {
74             $fileinfo['itemid'] = null;
75         }
76         if (empty($fileinfo['filename'])) {
77             $fileinfo['filename'] = null;
78         }
79         if (empty($fileinfo['filepath'])) {
80             $fileinfo['filepath'] = null;
81         }
82         try {
83             $browser = get_file_browser();
85             $return = array();
86             $return['parents'] = array();
87             $return['files'] = array();
88             $file = $browser->get_file_info($context, null, null, null, null);
89             if ($file = $browser->get_file_info($context, $fileinfo['component'], $fileinfo['filearea'], $fileinfo['itemid'], $fileinfo['filepath'], $fileinfo['filename'])) {
90                 $level = $file->get_parent();
91                 while ($level) {
92                     $params = $level->get_params();
93                     $params['filename'] = $level->get_visible_name();
94                     array_unshift($return['parents'], $params);
95                     $level = $level->get_parent();
96                 }
97                 $list = array();
98                 $children = $file->get_children();
99                 foreach ($children as $child) {
100                     $params = $child->get_params();
101                     if ($child->is_directory()) {
102                         $node = array(
103                             //TODO: this is wrong, you need to fetch info from the child node!!!!
104                             'contextid' => $params['contextid'],
105                             'component' => $params['component'],
106                             'filearea'  => $params['filearea'],
107                             'itemid'    => $params['itemid'],
108                             'filepath'  => $params['filepath'],
109                             'filename'  => $child->get_visible_name(),
110                             'url'       => null,
111                             'isdir'     =>true
112                         );
113                         $list[] = $node;
114                     } else {
115                         $node = array(
116                             //TODO: this is wrong, you need to fetch info from the child node!!!!
117                             'contextid' => $params['contextid'],
118                             'component' => $params['component'],
119                             'filearea'  => $params['filearea'],
120                             'itemid'    => $params['itemid'],
121                             'filepath'  => $params['filepath'],
122                             'filename'  => $child->get_visible_name(),
123                             'url'       => $child->get_url(),
124                             'isdir'     => false
125                         );
126                         $list[] = $node;
127                     }
128                 }
129             }
130             $return['files'] = $list;
131         } catch (Exception $e) {
132             throw $e;
133         }
134         return $return;
135     }
137     /**
138      * Returns description of get_files returns
139      * @return external_multiple_structure
140      */
141     public static function get_files_returns() {
142         return new external_single_structure(
143             array(
144                 'parents' => new external_multiple_structure(
145                     new external_single_structure(
146                         array(
147                             'contextid' => new external_value(PARAM_INT, ''),
148                             'component' => new external_value(PARAM_ALPHAEXT, ''),
149                             'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
150                             'itemid'    => new external_value(PARAM_INT, ''),
151                             'filepath'  => new external_value(PARAM_TEXT, ''),
152                             'filename'  => new external_value(PARAM_TEXT, ''),
153                         )
154                     )
155                 ),
156                 'files' => new external_multiple_structure(
157                     new external_single_structure(
158                         array(
159                             'contextid' => new external_value(PARAM_INT, ''),
160                             'component' => new external_value(PARAM_ALPHAEXT, ''),
161                             'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
162                             'itemid'   => new external_value(PARAM_INT, ''),
163                             'filepath' => new external_value(PARAM_TEXT, ''),
164                             'filename' => new external_value(PARAM_TEXT, ''),
165                             'isdir'    => new external_value(PARAM_BOOL, ''),
166                             'url'      => new external_value(PARAM_TEXT, ''),
167                         )
168                     )
169                 )
170             )
171         );
172     }
174     /**
175      * Returns description of upload parameters
176      * @return external_function_parameters
177      */
178     public static function upload_parameters() {
179         return new external_function_parameters(
180             array(
181                 'params' => new external_single_structure(array(
182                         'contextid' => new external_value(PARAM_INT, 'context id'),
183                         'filearea'  => new external_value(PARAM_ALPHAEXT, 'file area'),
184                         'component' => new external_value(PARAM_ALPHAEXT, 'component'),
185                         'itemid'    => new external_value(PARAM_INT, 'associated id'),
186                         'filepath'  => new external_value(PARAM_RAW, 'file path'),
187                         'filename'  => new external_value(PARAM_TEXT, 'file name'),
188                         'filecontent' => new external_value(PARAM_TEXT, 'file content')
189                     )
190                 )
191             )
192         );
193     }
195     /**
196      * Uploading a file to moodle
197      *
198      * @param array $fileinfo
199      * @return array
200      */
201     public static function upload($fileinfo) {
202         global $USER, $CFG;
203         debug('testing');
205         if (!isset($fileinfo['filecontent'])) {
206             throw new moodle_exception('nofile');
207         }
208         // saving file
209         if (!file_exists($CFG->dataroot.'/temp/wsupload')) {
210             mkdir($CFG->dataroot.'/temp/wsupload/', 0777, true);
211         }
213         if (is_dir($CFG->dataroot.'/temp/wsupload')) {
214             $dir = $CFG->dataroot.'/temp/wsupload/';
215         }
217         if (empty($fileinfo['filename'])) {
218             $filename = uniqid('wsupload').'_'.time().'.tmp';
219         } else {
220             $filename = $fileinfo['filename'];
221         }
223         if (file_exists($dir.$filename)) {
224             $filename = uniqid('m').$filename;
225         }
227         $savedfilepath = $dir.$filename;
229         file_put_contents($savedfilepath, base64_decode($fileinfo['filecontent']));
230         unset($fileinfo['filecontent']);
232         $component = $fileinfo['component'];
234         //TODO: mandatory!!!
235         if (!empty($fileinfo['filearea'])) {
236             $filearea = $fileinfo['filearea'];
237         } else {
238             $filearea = null;
239         }
241         if (!empty($fileinfo['filepath'])) {
242             $filepath = $fileinfo['filepath'];
243         } else {
244             $filepath = '';
245         }
247         if (isset($fileinfo['itemid'])) {
248             $itemid = $fileinfo['itemid'];
249         } else {
250             $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100);
251         }
252         if (!empty($fileinfo['contextid'])) {
253             $context = get_context_instance_by_id($fileinfo['contextid']);
254         } else {
255             $context = get_system_context();
256         }
259 // TODO: we MUST obey access control restrictions here, no messing with file_storage here, the only allowed way is to use file_browser here!!!!!!!!!!!!!!!!!!!!!!!!
260 throw new coding_exception('File upload ext api needs to be made secure first!!!!');
263         $browser = get_file_browser();
265         // check existing file
266         if ($file = $fs->get_file($context->id, $component, $filearea, $itemid, $filepath, $filename)) {
267             throw new moodle_exception('fileexist');
268         }
270         $file_record = new object();
271         $file_record->contextid = $context->id;
272         $file_record->component = $component;
273         $file_record->filearea  = $filearea;
274         $file_record->itemid    = $itemid;
275         $file_record->filepath  = $filepath;
276         $file_record->filename  = $filename;
277         $file_record->userid    = $USER->id;
279         // move file to filepool
280         try {
281             $file = $fs->create_file_from_pathname($file_record, $savedfilepath);
282             unlink($savedfilepath);
283         } catch (Exception $ex) {
284             throw $ex;
285         }
286         $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
288         return array(
289             'filename'=>$file->get_filename(),
290             'filepath'=>$file->get_filepath(),
291             'filearea'=>$file->get_filearea(),
292             'url'=>$info->get_url()
293             );
294     }
296     /**
297      * Returns description of upload returns
298      * @return external_multiple_structure
299      */
300     public static function upload_returns() {
301         return new external_single_structure(
302              array(
303                  'filename' => new external_value(PARAM_TEXT, ''),
304                  'filepath' => new external_value(PARAM_TEXT, ''),
305                  'filearea' => new external_value(PARAM_TEXT, ''),
306                  'url' => new external_value(PARAM_TEXT, ''),
307              )
308         );
309     }