MDL-25215, file extension should remain unchanged when using save as field in filepic...
[moodle.git] / repository / upload / lib.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  * A repository plugin to allow user uploading files
20  *
21  * @since 2.0
22  * @package    repository
23  * @subpackage upload
24  * @copyright  2009 Dongsheng Cai
25  * @author     Dongsheng Cai <dongsheng@moodle.com>
26  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27  */
29 class repository_upload extends repository {
30     private $mimetypes = array();
32     /**
33      * Print a upload form
34      * @return array
35      */
36     public function print_login() {
37         return $this->get_listing();
38     }
40     /**
41      * Process uploaded file
42      * @return array|bool
43      */
44     public function upload($saveas_filename, $maxbytes) {
45         global $USER, $CFG;
47         $types = optional_param('accepted_types', '*', PARAM_RAW);
48         if ((is_array($types) and in_array('*', $types)) or $types == '*') {
49             $this->mimetypes = '*';
50         } else {
51             foreach ($types as $type) {
52                 $this->mimetypes[] = mimeinfo('type', $type);
53             }
54         }
56         $record = new stdClass();
57         $record->filearea = 'draft';
58         $record->component = 'user';
59         $record->filepath = optional_param('savepath', '/', PARAM_PATH);
60         $record->itemid   = optional_param('itemid', 0, PARAM_INT);
61         $record->license  = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
62         $record->author   = optional_param('author', '', PARAM_TEXT);
64         $context = get_context_instance(CONTEXT_USER, $USER->id);
65         $elname = 'repo_upload_file';
67         $fs = get_file_storage();
68         $sm = get_string_manager();
70         if ($record->filepath !== '/') {
71             $record->filepath = file_correct_filepath($record->filepath);
72         }
74         if (!isset($_FILES[$elname])) {
75             throw new moodle_exception('nofile');
76         }
77         if (!empty($_FILES[$elname]['error'])) {
78             switch ($_FILES[$elname]['error']) {
79             case UPLOAD_ERR_INI_SIZE:
80                 throw new moodle_exception('upload_error_ini_size', 'repository_upload');
81                 break;
82             case UPLOAD_ERR_FORM_SIZE:
83                 throw new moodle_exception('upload_error_form_size', 'repository_upload');
84                 break;
85             case UPLOAD_ERR_PARTIAL:
86                 throw new moodle_exception('upload_error_partial', 'repository_upload');
87                 break;
88             case UPLOAD_ERR_NO_FILE:
89                 throw new moodle_exception('upload_error_no_file', 'repository_upload');
90                 break;
91             case UPLOAD_ERR_NO_TMP_DIR:
92                 throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
93                 break;
94             case UPLOAD_ERR_CANT_WRITE:
95                 throw new moodle_exception('upload_error_cant_write', 'repository_upload');
96                 break;
97             case UPLOAD_ERR_EXTENSION:
98                 throw new moodle_exception('upload_error_extension', 'repository_upload');
99                 break;
100             default:
101                 throw new moodle_exception('nofile');
102             }
103         }
105         if (empty($saveas_filename)) {
106             $record->filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
107         } else {
108             $ext = '';
109             $match = array();
110             $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
111             if (preg_match('/\.([a-z0-9]+)$/i', $filename, $match)) {
112                 if (isset($match[1])) {
113                     $ext = $match[1];
114                 }
115             }
116             $ext = !empty($ext) ? $ext : '';
117             if (preg_match('#\.(' . $ext . ')$#', $saveas_filename)) {
118                 // saveas filename contains file extension already
119                 $record->filename = $saveas_filename;
120             } else {
121                 $record->filename = $saveas_filename . '.' . $ext;
122             }
123         }
125         if ($this->mimetypes != '*') {
126             // check filetype
127             $filemimetype = mimeinfo('type', $_FILES[$elname]['name']);
128             if (!in_array($filemimetype, $this->mimetypes)) {
129                 if ($sm->string_exists($filemimetype, 'mimetypes')) {
130                     $filemimetype = get_string($filemimetype, 'mimetypes');
131                 }
132                 throw new moodle_exception('invalidfiletype', 'repository', '', $filemimetype);
133             }
134         }
136         if (empty($record->itemid)) {
137             $record->itemid = 0;
138         }
140         if (($maxbytes!==-1) && (filesize($_FILES[$elname]['tmp_name']) > $maxbytes)) {
141             throw new file_exception('maxbytes');
142         }
144         if ($file = $fs->get_file($context->id, $record->component, $record->filearea, $record->itemid, $record->filepath, $record->filename)) {
145             throw new moodle_exception('fileexists', 'repository');
146         }
148         $record->contextid = $context->id;
149         $record->userid    = $USER->id;
150         $record->source    = '';
152         $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
154         return array(
155             'url'=>moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(),
156             'id'=>$record->itemid,
157             'file'=>$record->filename);
158     }
160     /**
161      * Return a upload form
162      * @return array
163      */
164     public function get_listing() {
165         global $CFG;
166         $ret = array();
167         $ret['nologin']  = true;
168         $ret['nosearch'] = true;
169         $ret['norefresh'] = true;
170         $ret['list'] = array();
171         $ret['dynload'] = false;
172         $ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
173         return $ret;
174     }
176     /**
177      * supported return types
178      * @return int
179      */
180     public function supported_returntypes() {
181         return FILE_INTERNAL;
182     }
184     /**
185      * Upload file to local filesystem pool
186      * @param string $elname name of element
187      * @param string $filearea
188      * @param string $filepath
189      * @param string $filename - use specified filename, if not specified name of uploaded file used
190      * @param bool $override override file if exists
191      * @return mixed stored_file object or false if error; may throw exception if duplicate found
192      */
193     public function upload_to_filepool($elname, $record, $override = true) {
194     }