5e894500d225b9f8fcc371b2cc58d516c6649521
[moodle.git] / repository / draftfiles_ajax.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  * Draft file ajax file manager
20  *
21  * @package    core
22  * @subpackage repository
23  * @copyright  2010 Dongsheng Cai <dongsheng@moodle.com>
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 define('AJAX_SCRIPT', true);
29 require('../config.php');
30 require_once($CFG->libdir.'/filelib.php');
31 require_once($CFG->libdir.'/adminlib.php');
32 require_once($CFG->dirroot.'/repository/lib.php');
33 $PAGE->set_context(get_system_context());
34 require_login();
35 if (isguestuser()) {
36     print_error('noguest');
37 }
38 require_sesskey();
40 $action  = required_param('action', PARAM_ALPHA);
41 $draftid = required_param('itemid', PARAM_INT);
42 $filepath = optional_param('filepath', '/', PARAM_PATH);
44 $user_context = get_context_instance(CONTEXT_USER, $USER->id);
46 echo $OUTPUT->header(); // send headers
48 //
49 //NOTE TO ALL DEVELOPERS: this script must deal only with draft area of current user, it has to use only file_storage and no file_browser!!
50 //
52 switch ($action) {
53     case 'dir':
54         $data = new stdClass();
55         file_get_drafarea_folders($draftid, $filepath, $data);
56         echo json_encode($data);
57         die;
59     case 'list':
60         $filepath = optional_param('filepath', '/', PARAM_PATH);
62         $data = repository::prepare_listing(file_get_drafarea_files($draftid, $filepath));
63         $info = file_get_draft_area_info($draftid);
64         $data->filecount = $info['filecount'];
65         $data->filesize = $info['filesize'];
66         $data->tree = new stdClass();
67         file_get_drafarea_folders($draftid, '/', $data->tree);
68         echo json_encode($data);
69         die;
71     case 'mkdir':
72         $filepath   = required_param('filepath', PARAM_PATH);
73         $newdirname = required_param('newdirname', PARAM_FILE);
75         $fs = get_file_storage();
76         $fs->create_directory($user_context->id, 'user', 'draft', $draftid, file_correct_filepath(file_correct_filepath($filepath).$newdirname));
77         $return = new stdClass();
78         $return->filepath = $filepath;
79         echo json_encode($return);
80         die;
82     case 'delete':
83         $filename   = required_param('filename', PARAM_FILE);
84         $filepath   = required_param('filepath', PARAM_PATH);
86         $fs = get_file_storage();
87         $filepath = file_correct_filepath($filepath);
88         $return = new stdClass();
89         if ($stored_file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename)) {
90             $parent_path = $stored_file->get_parent_directory()->get_filepath();
91             if ($stored_file->is_directory()) {
92                 $files = $fs->get_directory_files($user_context->id, 'user', 'draft', $draftid, $filepath, true);
93                 foreach ($files as $file) {
94                     $file->delete();
95                 }
96                 $stored_file->delete();
97                 $return->filepath = $parent_path;
98                 echo json_encode($return);
99             } else {
100                 if($result = $stored_file->delete()) {
101                     $return->filepath = $parent_path;
102                     echo json_encode($return);
103                 } else {
104                     echo json_encode(false);
105                 }
106             }
107         } else {
108             echo json_encode(false);
109         }
110         die;
112     case 'setmainfile':
113         $filename   = required_param('filename', PARAM_FILE);
114         $filepath   = required_param('filepath', PARAM_PATH);
116         $filepath = file_correct_filepath($filepath);
117         // reset sort order
118         file_reset_sortorder($user_context->id, 'user', 'draft', $draftid);
119         // set main file
120         $return = file_set_sortorder($user_context->id, 'user', 'draft', $draftid, $filepath, $filename, 1);
121         echo json_encode($return);
122         die;
124     case 'updatefile':
125         // Allows to Rename file, move it to another directory, change it's license and author information in one request
126         $filename    = required_param('filename', PARAM_FILE);
127         $filepath    = required_param('filepath', PARAM_PATH);
129         $fs = get_file_storage();
130         if (!($file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename))) {
131             die(json_encode((object)array('error' => get_string('filenotfound', 'error'))));
132         }
134         $updatedata = array();
135         $updatedata['filename'] = $newfilename = optional_param('newfilename', $file->get_filename(), PARAM_FILE);
136         $updatedata['filepath'] = $newfilepath = optional_param('newfilepath', $file->get_filepath(), PARAM_PATH);
137         $updatedata['license'] = optional_param('newlicense', $file->get_license(), PARAM_TEXT);
138         $updatedata['author'] = optional_param('newauthor', $file->get_author(), PARAM_TEXT);
139         foreach ($updatedata as $key => $value) {
140             if (''.$value === ''.$file->{'get_'.$key}()) {
141                 unset($updatedata[$key]);
142             }
143         }
145         if (!empty($updatedata)) {
146             if (array_key_exists('filename', $updatedata) || array_key_exists('filepath', $updatedata)) {
147                 // check that target file name does not exist
148                 if ($fs->file_exists($user_context->id, 'user', 'draft', $draftid, $newfilepath, $newfilename)) {
149                     die(json_encode((object)array('error' => get_string('fileexists', 'repository'))));
150                 }
151                 $file->rename($newfilepath, $newfilename);
152             }
153             if (array_key_exists('license', $updatedata)) {
154                 $file->set_license($updatedata['license']);
155             }
156             if (array_key_exists('author', $updatedata)) {
157                 $file->set_author($updatedata['author']);
158             }
159             $changes = array_diff(array_keys($updatedata), array('filepath'));
160             if (!empty($changes)) {
161                 // any change except for the moving to another folder alters 'Date modified' of the file
162                 $file->set_timemodified(time());
163             }
164         }
166         die(json_encode((object)array('filepath' => $newfilepath)));
168     case 'updatedir':
169         $filepath = required_param('filepath', PARAM_PATH);
170         $fs = get_file_storage();
171         if (!$dir = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.')) {
172             die(json_encode((object)array('error' => get_string('foldernotfound', 'repository'))));
173         }
174         $parts = explode('/', trim($dir->get_filepath(), '/'));
175         $dirname = end($parts);
176         $newdirname = required_param('newdirname', PARAM_FILE);
177         $parent = required_param('newfilepath', PARAM_PATH);
178         $newfilepath = clean_param($parent . '/' . $newdirname . '/', PARAM_PATH);
179         if ($newfilepath == $filepath) {
180             // no action required
181             die(json_encode((object)array('filepath' => $parent)));
182         }
183         if ($fs->get_directory_files($user_context->id, 'user', 'draft', $draftid, $newfilepath, true)) {
184             //bad luck, we can not rename if something already exists there
185             die(json_encode((object)array('error' => get_string('folderexists', 'repository'))));
186         }
187         $xfilepath = preg_quote($filepath, '|');
188         if (preg_match("|^$xfilepath|", $parent)) {
189             // we can not move folder to it's own subfolder
190             die(json_encode((object)array('error' => get_string('folderrecurse', 'repository'))));
191         }
193         //we must update directory and all children too
194         $files = $fs->get_area_files($user_context->id, 'user', 'draft', $draftid);
195         foreach ($files as $file) {
196             if (!preg_match("|^$xfilepath|", $file->get_filepath())) {
197                 continue;
198             }
199             // move one by one
200             $path = preg_replace("|^$xfilepath|", $newfilepath, $file->get_filepath());
201             if ($dirname !== $newdirname && $file->get_filepath() === $filepath && $file->get_filename() === '.') {
202                 // this is the main directory we move/rename AND it has actually been renamed
203                 $file->set_timemodified(time());
204             }
205             $file->rename($path, $file->get_filename());
206         }
208         $return = new stdClass();
209         $return->filepath = $parent;
210         echo json_encode($return);
211         die;
213     case 'zip':
214         $filepath = required_param('filepath', PARAM_PATH);
216         $zipper = get_file_packer('application/zip');
217         $fs = get_file_storage();
219         $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.');
221         $parent_path = $file->get_parent_directory()->get_filepath();
223         $filepath = explode('/', trim($file->get_filepath(), '/'));
224         $filepath = array_pop($filepath);
226         if ($newfile = $zipper->archive_to_storage(array($filepath => $file), $user_context->id, 'user', 'draft', $draftid, $parent_path, $filepath.'.zip', $USER->id)) {
227             $return = new stdClass();
228             $return->filepath = $parent_path;
229             echo json_encode($return);
230         } else {
231             echo json_encode(false);
232         }
233         die;
235     case 'downloaddir':
236         $filepath = required_param('filepath', PARAM_PATH);
238         $zipper = get_file_packer('application/zip');
239         $fs = get_file_storage();
240         $area = file_get_draft_area_info($draftid);
241         if ($area['filecount'] == 0) {
242             echo json_encode(false);
243             die;
244         }
246         $stored_file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.');
247         if ($filepath === '/') {
248             $filename = get_string('files').'.zip';
249         } else {
250             $filename = explode('/', trim($filepath, '/'));
251             $filename = array_pop($filename) . '.zip';
252         }
254         // archive compressed file to an unused draft area
255         $newdraftitemid = file_get_unused_draft_itemid();
256         if ($newfile = $zipper->archive_to_storage(array('/' => $stored_file), $user_context->id, 'user', 'draft', $newdraftitemid, '/', $filename, $USER->id)) {
257             $return = new stdClass();
258             $return->fileurl  = moodle_url::make_draftfile_url($newdraftitemid, '/', $filename)->out();
259             $return->filepath = $filepath;
260             echo json_encode($return);
261         } else {
262             echo json_encode(false);
263         }
264         die;
266     case 'unzip':
267         $filename = required_param('filename', PARAM_FILE);
268         $filepath = required_param('filepath', PARAM_PATH);
270         $zipper = get_file_packer('application/zip');
272         $fs = get_file_storage();
274         $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename);
276         if ($newfile = $file->extract_to_storage($zipper, $user_context->id, 'user', 'draft', $draftid, $filepath, $USER->id)) {
277             $return = new stdClass();
278             $return->filepath = $filepath;
279             echo json_encode($return);
280         } else {
281             echo json_encode(false);
282         }
283         die;
285     case 'getoriginal':
286         $filename    = required_param('filename', PARAM_FILE);
287         $filepath    = required_param('filepath', PARAM_PATH);
289         $fs = get_file_storage();
290         $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename);
291         if (!$file) {
292             echo json_encode(false);
293         } else {
294             $return = array('filename' => $filename, 'filepath' => $filepath, 'original' => $file->get_reference_details());
295             echo json_encode((object)$return);
296         }
297         die;
299     case 'getreferences':
300         $filename    = required_param('filename', PARAM_FILE);
301         $filepath    = required_param('filepath', PARAM_PATH);
303         $fs = get_file_storage();
304         $file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, $filename);
305         if (!$file) {
306             echo json_encode(false);
307         } else {
308             $source = unserialize($file->get_source());
309             $return = array('filename' => $filename, 'filepath' => $filepath, 'references' => array());
310             $browser = get_file_browser();
311             if (isset($source->original)) {
312                 $reffiles = $fs->search_references($source->original);
313                 foreach ($reffiles as $reffile) {
314                     $refcontext = get_context_instance_by_id($reffile->get_contextid());
315                     $fileinfo = $browser->get_file_info($refcontext, $reffile->get_component(), $reffile->get_filearea(), $reffile->get_itemid(), $reffile->get_filepath(), $reffile->get_filename());
316                     if (empty($fileinfo)) {
317                         $return['references'][] = get_string('undisclosedreference', 'repository');
318                     } else {
319                         $return['references'][] = $fileinfo->get_readable_fullname();
320                     }
321                 }
322             }
323             echo json_encode((object)$return);
324         }
325         die;
327     default:
328         // no/unknown action?
329         echo json_encode(false);
330         die;