dff8b15ddac17b7a89bb55867747a10303c7e7e0
[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                             'contextid' => $params['contextid'],
104                             'component' => $params['component'],
105                             'filearea'  => $params['filearea'],
106                             'itemid'    => $params['itemid'],
107                             'filepath'  => $params['filepath'],
108                             'filename'  => $child->get_visible_name(),
109                             'url'       => null,
110                             'isdir'     =>true
111                         );
112                         $list[] = $node;
113                     } else {
114                         $node = array(
115                             'contextid' => $params['contextid'],
116                             'component' => $params['component'],
117                             'filearea'  => $params['filearea'],
118                             'itemid'    => $params['itemid'],
119                             'filepath'  => $params['filepath'],
120                             'filename'  => $child->get_visible_name(),
121                             'url'       => $child->get_url(),
122                             'isdir'     => false
123                         );
124                         $list[] = $node;
125                     }
126                 }
127             }
128             $return['files'] = $list;
129         } catch (Exception $e) {
130             throw $e;
131         }
132         return $return;
133     }
135     /**
136      * Returns description of get_files returns
137      * @return external_multiple_structure
138      */
139     public static function get_files_returns() {
140         return new external_single_structure(
141             array(
142                 'parents' => new external_multiple_structure(
143                     new external_single_structure(
144                         array(
145                             'contextid' => new external_value(PARAM_INT, ''),
146                             'component' => new external_value(PARAM_ALPHAEXT, ''),
147                             'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
148                             'itemid'    => new external_value(PARAM_INT, ''),
149                             'filepath'  => new external_value(PARAM_TEXT, ''),
150                             'filename'  => new external_value(PARAM_TEXT, ''),
151                         )
152                     )
153                 ),
154                 'files' => new external_multiple_structure(
155                     new external_single_structure(
156                         array(
157                             'contextid' => new external_value(PARAM_INT, ''),
158                             'component' => new external_value(PARAM_ALPHAEXT, ''),
159                             'filearea'  => new external_value(PARAM_ALPHAEXT, ''),
160                             'itemid'   => new external_value(PARAM_INT, ''),
161                             'filepath' => new external_value(PARAM_TEXT, ''),
162                             'filename' => new external_value(PARAM_TEXT, ''),
163                             'isdir'    => new external_value(PARAM_BOOL, ''),
164                             'url'      => new external_value(PARAM_TEXT, ''),
165                         )
166                     )
167                 )
168             )
169         );
170     }
172     /**
173      * Returns description of upload parameters
174      * @return external_function_parameters
175      */
176     public static function upload_parameters() {
177         return new external_function_parameters(
178             array(
179                 'params' => new external_single_structure(array(
180                         'contextid' => new external_value(PARAM_INT, 'context id'),
181                         'filearea'  => new external_value(PARAM_ALPHAEXT, 'file area'),
182                         'component' => new external_value(PARAM_ALPHAEXT, 'component'),
183                         'itemid'    => new external_value(PARAM_INT, 'associated id'),
184                         'filepath'  => new external_value(PARAM_RAW, 'file path'),
185                         'filename'  => new external_value(PARAM_TEXT, 'file name'),
186                         'filecontent' => new external_value(PARAM_TEXT, 'file content')
187                     )
188                 )
189             )
190         );
191     }
193     /**
194      * Uploading a file to moodle
195      *
196      * @param array $fileinfo
197      * @return array
198      */
199     public static function upload($fileinfo) {
200         global $USER, $CFG;
201         debug('testing');
203         if (!isset($fileinfo['filecontent'])) {
204             throw new moodle_exception('nofile');
205         }
206         // saving file
207         if (!file_exists($CFG->dataroot.'/temp/wsupload')) {
208             mkdir($CFG->dataroot.'/temp/wsupload/', 0777, true);
209         }
211         if (is_dir($CFG->dataroot.'/temp/wsupload')) {
212             $dir = $CFG->dataroot.'/temp/wsupload/';
213         }
215         if (empty($fileinfo['filename'])) {
216             $filename = uniqid('wsupload').'_'.time().'.tmp';
217         } else {
218             $filename = $fileinfo['filename'];
219         }
221         if (file_exists($dir.$filename)) {
222             $filename = uniqid('m').$filename;
223         }
225         $savedfilepath = $dir.$filename;
227         file_put_contents($savedfilepath, base64_decode($fileinfo['filecontent']));
228         unset($fileinfo['filecontent']);
230         $component = $fileinfo['component'];
232         //TODO: mandatory!!!
233         if (!empty($fileinfo['filearea'])) {
234             $filearea = $fileinfo['filearea'];
235         } else {
236             $filearea = null;
237         }
239         if (!empty($fileinfo['filepath'])) {
240             $filepath = $fileinfo['filepath'];
241         } else {
242             $filepath = '';
243         }
245         if (isset($fileinfo['itemid'])) {
246             $itemid = $fileinfo['itemid'];
247         } else {
248             $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100);
249         }
250         if (!empty($fileinfo['contextid'])) {
251             $context = get_context_instance_by_id($fileinfo['contextid']);
252         } else {
253             $context = get_system_context();
254         }
257 // TODO: we MUST obey access control restrictions here, no messing with file_storage here, the only allowed way is to use file_browser here!!!!!!!!!!!!!!!!!!!!!!!!
258 throw new coding_exception('File upload ext api needs to be made secure first!!!!');
261         $browser = get_file_browser();
263         // check existing file
264         if ($file = $fs->get_file($context->id, $component, $filearea, $itemid, $filepath, $filename)) {
265             throw new moodle_exception('fileexist');
266         }
268         $file_record = new object();
269         $file_record->contextid = $context->id;
270         $file_record->component = $component;
271         $file_record->filearea  = $filearea;
272         $file_record->itemid    = $itemid;
273         $file_record->filepath  = $filepath;
274         $file_record->filename  = $filename;
275         $file_record->userid    = $USER->id;
277         // move file to filepool
278         try {
279             $file = $fs->create_file_from_pathname($file_record, $savedfilepath);
280             unlink($savedfilepath);
281         } catch (Exception $ex) {
282             throw $ex;
283         }
284         $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
286         return array(
287             'filename'=>$file->get_filename(),
288             'filepath'=>$file->get_filepath(),
289             'filearea'=>$file->get_filearea(),
290             'url'=>$info->get_url()
291             );
292     }
294     /**
295      * Returns description of upload returns
296      * @return external_multiple_structure
297      */
298     public static function upload_returns() {
299         return new external_single_structure(
300              array(
301                  'filename' => new external_value(PARAM_TEXT, ''),
302                  'filepath' => new external_value(PARAM_TEXT, ''),
303                  'filearea' => new external_value(PARAM_TEXT, ''),
304                  'url' => new external_value(PARAM_TEXT, ''),
305              )
306         );
307     }