Fixing problems like in [MDL-22352].
[moodle.git] / repository / repository_ajax.php
CommitLineData
aa6c1ced 1<?php
5bce5972 2
6f2cd52a
DC
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/>.
17
18
19/**
20 * The Web service script that is called from the filepicker front end
21 *
22 * @since 2.0
23 * @package moodlecore
24 * @subpackage repository
25 * @copyright 2009 Dongsheng Cai <dongsheng@moodle.com>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
455860ce 28
14469892
DC
29require_once(dirname(dirname(__FILE__)).'/config.php');
30require_once(dirname(dirname(__FILE__)).'/lib/filelib.php');
31require_once(dirname(__FILE__).'/lib.php');
99eaca9d 32
9d4ef80f 33require_login();
cf493e89 34
d0f8585d 35/// Parameters
9d4ef80f 36$action = optional_param('action', '', PARAM_ALPHA);
f8df83f3 37$repo_id = optional_param('repo_id', 0, PARAM_INT); // repository ID
9d4ef80f 38$callback = optional_param('callback', '', PARAM_CLEANHTML);
d10c92f3
DC
39$client_id = optional_param('client_id', '', PARAM_RAW); // client ID
40$contextid = optional_param('ctx_id', SYSCONTEXTID, PARAM_INT); // context ID
9d4ef80f 41$env = optional_param('env', 'filepicker', PARAM_ALPHA); // opened in editor or moodleform
1dce6261
DC
42$license = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
43$author = optional_param('author', '', PARAM_TEXT);
14469892 44$source = optional_param('source', '', PARAM_RAW); // file to download
9d4ef80f 45$itemid = optional_param('itemid', 0, PARAM_INT);
9d4ef80f 46$page = optional_param('page', '', PARAM_RAW); // page
b8cea715 47$maxbytes = optional_param('maxbytes', 0, PARAM_INT);
9d4ef80f 48$req_path = optional_param('p', '', PARAM_RAW); // path
14469892
DC
49$saveas_filearea = optional_param('filearea', 'user_draft', PARAM_TEXT);
50$saveas_filename = optional_param('title', '', PARAM_FILE); // new file name
7e4944c8 51$saveas_path = optional_param('savepath', '/', PARAM_PATH);
9d4ef80f
DC
52$search_text = optional_param('s', '', PARAM_CLEANHTML);
53$linkexternal = optional_param('linkexternal', '', PARAM_ALPHA);
455860ce 54
577aab9b 55/// Headers to make it not cacheable
9d4ef80f
DC
56header('Cache-Control: no-cache, must-revalidate');
57header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
58
59$err = new stdclass;
60$err->client_id = $client_id;
0eb58cf4 61
ea1780ad
DC
62$moodle_maxbytes = get_max_upload_file_size();
63// to prevent maxbytes greater than moodle maxbytes setting
64if ($maxbytes == 0 || $maxbytes>=$moodle_maxbytes) {
65 $maxbytes = $moodle_maxbytes;
b8cea715
DC
66}
67
d0f8585d 68/// Check permissions
9d4ef80f
DC
69if (! (isloggedin() && repository::check_context($contextid)) ) {
70 $err->e = get_string('nopermissiontoaccess', 'repository');
71 die(json_encode($err));
72}
0eb58cf4 73
577aab9b 74/// Wait as long as it takes for this script to finish
9d4ef80f 75set_time_limit(0);
577aab9b 76
9d4ef80f
DC
77// Early actions which need to be done before repository instaces initialised
78switch ($action) {
79 // global search
80 case 'gsearch':
81 $params = array();
82 $params['context'] = array(get_context_instance_by_id($contextid), get_system_context());
83 $params['currentcontext'] = get_context_instance_by_id($contextid);
84 $repos = repository::get_instances($params);
85 $list = array();
86 foreach($repos as $repo){
87 if ($repo->global_search()) {
88 try {
89 $ret = $repo->search($search_text);
90 array_walk($ret['list'], 'repository_attach_id', $repo->id); // See function below
91 $tmp = array_merge($list, $ret['list']);
92 $list = $tmp;
93 } catch (repository_exception $e) {
94 $err->e = $e->getMessage();
95 die(json_encode($err));
d0f8585d 96 }
97 }
9d4ef80f
DC
98 }
99 $listing = array('list'=>$list);
100 $listing['gsearch'] = true;
101 $listing['client_id'] = $client_id;
102 die(json_encode($listing));
103 break;
d0f8585d 104
9d4ef80f
DC
105 // remove the cache files & logout
106 case 'ccache':
107 $cache = new curl_cache;
108 $cache->refresh();
109 $action = 'list';
110 break;
111}
d0f8585d 112
113/// Get repository instance information
9d4ef80f
DC
114$sql = 'SELECT i.name, i.typeid, r.type FROM {repository} r, {repository_instances} i '.
115 'WHERE i.id=? AND i.typeid=r.id';
d0f8585d 116
9d4ef80f
DC
117if (!$repository = $DB->get_record_sql($sql, array($repo_id))) {
118 $err->e = get_string('invalidrepositoryid', 'repository');
119 die(json_encode($err));
120} else {
121 $type = $repository->type;
122}
123
124if (file_exists($CFG->dirroot.'/repository/'.$type.'/repository.class.php')) {
125 require_once($CFG->dirroot.'/repository/'.$type.'/repository.class.php');
126 $classname = 'repository_' . $type;
127 try {
128 $repo = new $classname($repo_id, $contextid, array('ajax'=>true, 'name'=>$repository->name, 'type'=>$type, 'client_id'=>$client_id));
129 } catch (repository_exception $e){
130 $err->e = $e->getMessage();
bf1fccf0 131 die(json_encode($err));
5bce5972 132 }
a06878d3 133} else {
9d4ef80f
DC
134 $err->e = get_string('invalidplugin', 'repository', $type);
135 die(json_encode($err));
a06878d3 136}
9d4ef80f
DC
137
138
139if (!empty($callback)) {
140 // call opener window to refresh repository
141 // the callback url should be something like this:
142 // http://xx.moodle.com/repository/repository_ajax.php?callback=yes&repo_id=1&sid=xxx
143 // sid is the attached auth token from external source
144 // If Moodle is working on HTTPS mode, then we are not allowed to access
145 // parent window, in this case, we need to alert user to refresh the repository
146 // manually.
147 $strhttpsbug = get_string('cannotaccessparentwin', 'repository');
148 $strrefreshnonjs = get_string('refreshnonjsfilepicker', 'repository');
149 $js =<<<EOD
150<html>
151<head>
152 <script type="text/javascript">
153 if(window.opener){
154 window.opener.M.core_filepicker.active_filepicker.list();
155 window.close();
156 } else {
157 alert("{$strhttpsbug }");
158 }
159 </script>
160</head>
5e98ab96 161<body>
9d4ef80f 162 <noscript>
99eaca9d 163 {$strrefreshnonjs}
9d4ef80f 164 </noscript>
5e98ab96 165</body>
166</html>
d0f8585d 167EOD;
9d4ef80f
DC
168 die($js);
169}
d0f8585d 170
171/// These actions all occur on the currently active repository instance
9d4ef80f
DC
172switch ($action) {
173 case 'sign':
174 case 'signin':
175 case 'list':
176 if ($repo->check_login()) {
d0f8585d 177 try {
9d4ef80f 178 $listing = $repo->get_listing($req_path, $page);
e189ec00 179 $listing['client_id'] = $client_id;
180 $listing['repo_id'] = $repo_id;
181 echo json_encode($listing);
d0f8585d 182 } catch (repository_exception $e) {
d0f8585d 183 $err->e = $e->getMessage();
184 die(json_encode($err));
185 }
186 break;
9d4ef80f
DC
187 } else {
188 $action = 'login';
189 }
190 case 'login':
191 try {
192 $listing = $repo->print_login();
193 $listing['client_id'] = $client_id;
194 $listing['repo_id'] = $repo_id;
195 echo json_encode($listing);
196 } catch (repository_exception $e){
197 $err->e = $e->getMessage();
198 die(json_encode($err));
199 }
200 break;
201 case 'logout':
202 $logout = $repo->logout();
203 $logout['client_id'] = $client_id;
204 $logout['repo_id'] = $repo_id;
205 echo json_encode($logout);
206 break;
207 case 'searchform':
208 $search_form['form'] = $repo->print_search($client_id);
209 $search_form['client_id'] = $client_id;
210 echo json_encode($search_form);
211 break;
212 case 'search':
213 try {
214 $search_result = $repo->search($search_text, (int)$page);
215 $search_result['client_id'] = $client_id;
216 $search_result['repo_id'] = $repo_id;
217 $search_result['search_result'] = true;
218 echo json_encode($search_result);
219 } catch (repository_exception $e) {
220 $err->e = $e->getMessage();
221 die(json_encode($err));
222 }
223 break;
224 case 'download':
225 try {
ea1780ad
DC
226 // We have two special repoisitory type need to deal with
227 // local and recent plugins don't added new files to moodle, just add new records to database
228 // so we don't check user quota and maxbytes here
7f288e50 229 if ($repo->options['type'] == 'local' || $repo->options['type'] == 'recent' ) {
acb70a9b 230 try {
c7e4621e 231 $fileinfo = $repo->copy_to_area($source, $saveas_filearea, $itemid, $saveas_path, $saveas_filename);
acb70a9b
DC
232 } catch (Exception $e) {
233 throw $e;
234 }
9d4ef80f
DC
235 $info = array();
236 $info['client_id'] = $client_id;
237 $info['file'] = $fileinfo['title'];
238 $info['id'] = $itemid;
239 $info['url'] = $CFG->httpswwwroot.'/draftfile.php/'.$fileinfo['contextid'].'/user_draft/'.$itemid.'/'.$fileinfo['title'];
240 $filesize = $fileinfo['filesize'];
acb70a9b 241 if (($maxbytes!==-1) && ($filesize>$maxbytes)) {
dd64051e 242 throw new file_exception('maxbytes');
41076c58 243 }
acb70a9b
DC
244 echo json_encode($info);
245 die; // ends here!!
9d4ef80f 246 } else {
acb70a9b
DC
247 $allowexternallink = (int)get_config(null, 'repositoryallowexternallinks');
248 if (!empty($allowexternallink)) {
249 $allowexternallink = true;
250 } else {
251 $allowexternallink = false;
99d52655 252 }
acb70a9b
DC
253 // allow external links in url element all the time
254 $allowexternallink = ($allowexternallink || ($env == 'url'));
99d52655 255
ea1780ad 256 // Use link of the files
acb70a9b
DC
257 if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() || FILE_EXTERNAL)) {
258 // use external link
259 try {
260 $link = $repo->get_link($source);
261 } catch (repository_exception $e){
ea1780ad 262 throw $e;
acb70a9b
DC
263 }
264 $info = array();
265 $info['filename'] = $saveas_filename;
266 $info['type'] = 'link';
267 $info['url'] = $link;
268 echo json_encode($info);
269 die;
270 } else {
ea1780ad 271 // Download file to moodle
acb70a9b
DC
272 $file = $repo->get_file($source, $saveas_filename);
273 if ($file['path'] === false) {
274 $err->e = get_string('cannotdownload', 'repository');
275 die(json_encode($err));
276 }
ea1780ad
DC
277
278 // check if exceed maxbytes
acb70a9b 279 if (($maxbytes!==-1) && (filesize($file['path']) > $maxbytes)) {
dd64051e 280 throw new file_exception('maxbytes');
acb70a9b 281 }
14469892 282
ea1780ad
DC
283 // check if exceed user quota
284 $userquota = file_get_user_used_space();
285 if (filesize($file['path'])+$userquota>=(int)$CFG->userquota) {
286 throw new file_exception('userquotalimit');
287 }
288
acb70a9b
DC
289 $record = new stdclass;
290 $record->filepath = $saveas_path;
291 $record->filename = $saveas_filename;
292 $record->filearea = $saveas_filearea;
293 $record->itemid = $itemid;
14469892 294
acb70a9b
DC
295 if (!empty($file['license'])) {
296 $record->license = $file['license'];
297 } else {
298 $record->license = $license;
299 }
300 if (!empty($file['author'])) {
301 $record->author = $file['author'];
302 } else {
303 $record->author = $author;
304 }
305 $record->source = !empty($file['url']) ? $file['url'] : '';
1dce6261 306
acb70a9b
DC
307 $info = repository::move_to_filepool($file['path'], $record);
308 if (empty($info)) {
309 $info['e'] = get_string('error', 'moodle');
310 }
311 echo json_encode($info);
312 die;
313 }
9d4ef80f 314 }
9d4ef80f
DC
315 } catch (Exception $e) {
316 $err->e = $e->getMessage();
317 die(json_encode($err));
318 }
319 break;
320 case 'upload':
321 try {
1dce6261 322 $result = $repo->upload();
9d4ef80f
DC
323 $result['client_id'] = $client_id;
324 echo json_encode($result);
325 } catch (Exception $e){
326 $err->e = $e->getMessage();
327 $err->client_id = $client_id;
328 die(json_encode($err));
329 }
330 break;
331}
d0f8585d 332
333/**
334 * Small function to walk an array to attach repository ID
9d4ef80f
DC
335 * @param array $value
336 * @param string $key
337 * @param int $id
d0f8585d 338 */
339function repository_attach_id(&$value, $key, $id){
340 $value['repo_id'] = $id;
0eb58cf4 341}