"MDL-20904, web services for files"
[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                         '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'),
45                     )
46                 )
47             )
48         );
49     }
51     /**
52      * Return moodle files listing
53      * @param array $fileinfo
54      * @return array
55      */
56     public static function get_files($fileinfo) {
57         global $CFG, $USER, $OUTPUT;
58         if (empty($fileinfo['itemid'])) {
59             $fileinfo['itemid'] = null;
60         }
61         if (empty($fileinfo['filename'])) {
62             $fileinfo['filename'] = null;
63         }
64         if (empty($fileinfo['filepath'])) {
65             $fileinfo['filepath'] = null;
66         }
67         if (empty($fileinfo['filearea'])) {
68             $fileinfo['filearea'] = null;
69         }
70         if (empty($fileinfo['contextid'])) {
71             $context  = get_system_context();
72         } else {
73             $context  = get_context_instance_by_id($fileinfo['contextid']);
74         }
75         try {
76             $browser = get_file_browser();
78             $return = array();
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();
84                 while ($level) {
85                     $params = $level->get_params();
86                     $params['filename'] = $level->get_visible_name();
87                     array_unshift($return['parents'], $params);
88                     $level = $level->get_parent();
89                 }
90                 $list = array();
91                 $children = $file->get_children();
92                 foreach ($children as $child) {
93                     $params = $child->get_params();
94                     if ($child->is_directory()) {
95                         $node = array(
96                             'filename' => $child->get_visible_name(),
97                             'filepath' => $params['filepath'],
98                             'filearea' => $params['filearea'],
99                             'itemid' => $params['itemid'],
100                             'contextid' => $params['contextid'],
101                             'url' => null,
102                             'isdir'=>true
103                         );
104                         $list[] = $node;
105                     } else {
106                         $node = array(
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(),
113                             'isdir'=>false
114                         );
115                         $list[] = $node;
116                     }
117                 }
118             }
119             $return['files'] = $list;
120         } catch (Exception $e) {
121             throw $e;
122         }
123         return $return;
124     }
126     /**
127      * Returns description of get_files returns
128      * @return external_multiple_structure
129      */
130     public static function get_files_returns() {
131         return new external_single_structure(
132             array(
133                 'parents' => new external_multiple_structure(
134                     new external_single_structure(
135                         array(
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, '')
141                         )
142                     )
143                 ),
144                 'files' => new external_multiple_structure(
145                     new external_single_structure(
146                         array(
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, '')
154                         )
155                     )
156                 )
157             )
158         );
159     }
161     /**
162      * Returns description of upload parameters
163      * @return external_function_parameters
164      */
165     public static function upload_parameters() {
166         return new external_function_parameters(
167             array(
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')
175                     )
176                 )
177             )
178         );
179     }
181     /**
182      * Uploading a file to moodle
183      *
184      * @param array $fileinfo
185      * @return array
186      */
187     public static function upload($fileinfo) {
188         global $USER, $CFG;
189         debug('testing');
191         if (!isset($fileinfo['filecontent'])) {
192             throw new moodle_exception('nofile');
193         }
194         // saving file
195         if (!file_exists($CFG->dataroot.'/temp/wsupload')) {
196             mkdir($CFG->dataroot.'/temp/wsupload/', 0777, true);
197         }
199         if (is_dir($CFG->dataroot.'/temp/wsupload')) {
200             $dir = $CFG->dataroot.'/temp/wsupload/';
201         }
203         if (empty($fileinfo['filename'])) {
204             $filename = uniqid('wsupload').'_'.time().'.tmp';
205         } else {
206             $filename = $fileinfo['filename'];
207         }
209         if (file_exists($dir.$filename)) {
210             $filename = uniqid('m').$filename;
211         }
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'];
220         } else {
221             $filearea = null;
222         }
224         if (!empty($fileinfo['filepath'])) {
225             $filepath = $fileinfo['filepath'];
226         } else {
227             $filepath = '';
228         }
229  
230         if (isset($fileinfo['itemid'])) {
231             $itemid = $fileinfo['itemid'];
232         } else {
233             $itemid = (int)substr(hexdec(uniqid()), 0, 9)+rand(1,100);
234         }
235         if (!empty($fileinfo['contextid'])) {
236             $context = get_context_instance_by_id($fileinfo['contextid']);
237         } else {
238             $context = get_system_context();
239         }
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');
247         }
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
258         try {
259             $file = $fs->create_file_from_pathname($file_record, $savedfilepath);
260             unlink($savedfilepath);
261         } catch (Exception $ex) {
262             throw $ex;
263         }
264         $info = $browser->get_file_info($context, $file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $file->get_filename());
266         return array(
267             'filename'=>$file->get_filename(),
268             'filepath'=>$file->get_filepath(),
269             'filearea'=>$file->get_filearea(),
270             'url'=>$info->get_url()
271             );
272     }
274     /**
275      * Returns description of upload returns
276      * @return external_multiple_structure
277      */
278     public static function upload_returns() {
279         return new external_single_structure(
280              array(
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, ''),
285              )
286         );
287     }