PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/repository/upload/lib.php

https://github.com/kpike/moodle
PHP | 204 lines | 139 code | 21 blank | 44 comment | 22 complexity | e4dae5a6b35f194501ec066e953d8fc9 MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * A repository plugin to allow user uploading files
  18. *
  19. * @since 2.0
  20. * @package repository
  21. * @subpackage upload
  22. * @copyright 2009 Dongsheng Cai
  23. * @author Dongsheng Cai <dongsheng@moodle.com>
  24. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25. */
  26. class repository_upload extends repository {
  27. private $mimetypes = array();
  28. /**
  29. * Print a upload form
  30. * @return array
  31. */
  32. public function print_login() {
  33. return $this->get_listing();
  34. }
  35. /**
  36. * Process uploaded file
  37. * @return array|bool
  38. */
  39. public function upload($saveas_filename, $maxbytes) {
  40. global $USER, $CFG;
  41. $types = optional_param_array('accepted_types', '*', PARAM_RAW);
  42. if ((is_array($types) and in_array('*', $types)) or $types == '*') {
  43. $this->mimetypes = '*';
  44. } else {
  45. foreach ($types as $type) {
  46. $this->mimetypes[] = mimeinfo('type', $type);
  47. }
  48. }
  49. $record = new stdClass();
  50. $record->filearea = 'draft';
  51. $record->component = 'user';
  52. $record->filepath = optional_param('savepath', '/', PARAM_PATH);
  53. $record->itemid = optional_param('itemid', 0, PARAM_INT);
  54. $record->license = optional_param('license', $CFG->sitedefaultlicense, PARAM_TEXT);
  55. $record->author = optional_param('author', '', PARAM_TEXT);
  56. $context = get_context_instance(CONTEXT_USER, $USER->id);
  57. $elname = 'repo_upload_file';
  58. $fs = get_file_storage();
  59. $sm = get_string_manager();
  60. if ($record->filepath !== '/') {
  61. $record->filepath = file_correct_filepath($record->filepath);
  62. }
  63. if (!isset($_FILES[$elname])) {
  64. throw new moodle_exception('nofile');
  65. }
  66. if (!empty($_FILES[$elname]['error'])) {
  67. switch ($_FILES[$elname]['error']) {
  68. case UPLOAD_ERR_INI_SIZE:
  69. throw new moodle_exception('upload_error_ini_size', 'repository_upload');
  70. break;
  71. case UPLOAD_ERR_FORM_SIZE:
  72. throw new moodle_exception('upload_error_form_size', 'repository_upload');
  73. break;
  74. case UPLOAD_ERR_PARTIAL:
  75. throw new moodle_exception('upload_error_partial', 'repository_upload');
  76. break;
  77. case UPLOAD_ERR_NO_FILE:
  78. throw new moodle_exception('upload_error_no_file', 'repository_upload');
  79. break;
  80. case UPLOAD_ERR_NO_TMP_DIR:
  81. throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
  82. break;
  83. case UPLOAD_ERR_CANT_WRITE:
  84. throw new moodle_exception('upload_error_cant_write', 'repository_upload');
  85. break;
  86. case UPLOAD_ERR_EXTENSION:
  87. throw new moodle_exception('upload_error_extension', 'repository_upload');
  88. break;
  89. default:
  90. throw new moodle_exception('nofile');
  91. }
  92. }
  93. // scan the files, throws exception and deletes if virus found
  94. // this is tricky because clamdscan daemon might not be able to access the files
  95. $permissions = fileperms($_FILES[$elname]['tmp_name']);
  96. @chmod($_FILES[$elname]['tmp_name'], $CFG->filepermissions);
  97. self::antivir_scan_file($_FILES[$elname]['tmp_name'], $_FILES[$elname]['name'], true);
  98. @chmod($_FILES[$elname]['tmp_name'], $permissions);
  99. if (empty($saveas_filename)) {
  100. $record->filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
  101. } else {
  102. $ext = '';
  103. $match = array();
  104. $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
  105. if (preg_match('/\.([a-z0-9]+)$/i', $filename, $match)) {
  106. if (isset($match[1])) {
  107. $ext = $match[1];
  108. }
  109. }
  110. $ext = !empty($ext) ? $ext : '';
  111. if (preg_match('#\.(' . $ext . ')$#i', $saveas_filename)) {
  112. // saveas filename contains file extension already
  113. $record->filename = $saveas_filename;
  114. } else {
  115. $record->filename = $saveas_filename . '.' . $ext;
  116. }
  117. }
  118. if ($this->mimetypes != '*') {
  119. // check filetype
  120. $filemimetype = mimeinfo('type', $_FILES[$elname]['name']);
  121. if (!in_array($filemimetype, $this->mimetypes)) {
  122. if ($sm->string_exists($filemimetype, 'mimetypes')) {
  123. $filemimetype = get_string($filemimetype, 'mimetypes');
  124. }
  125. throw new moodle_exception('invalidfiletype', 'repository', '', $filemimetype);
  126. }
  127. }
  128. if (empty($record->itemid)) {
  129. $record->itemid = 0;
  130. }
  131. if (($maxbytes!==-1) && (filesize($_FILES[$elname]['tmp_name']) > $maxbytes)) {
  132. throw new file_exception('maxbytes');
  133. }
  134. $record->contextid = $context->id;
  135. $record->userid = $USER->id;
  136. $record->source = '';
  137. if (repository::draftfile_exists($record->itemid, $record->filepath, $record->filename)) {
  138. $existingfilename = $record->filename;
  139. $unused_filename = repository::get_unused_filename($record->itemid, $record->filepath, $record->filename);
  140. $record->filename = $unused_filename;
  141. $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
  142. $event = array();
  143. $event['event'] = 'fileexists';
  144. $event['newfile'] = new stdClass;
  145. $event['newfile']->filepath = $record->filepath;
  146. $event['newfile']->filename = $unused_filename;
  147. $event['newfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $unused_filename)->out();
  148. $event['existingfile'] = new stdClass;
  149. $event['existingfile']->filepath = $record->filepath;
  150. $event['existingfile']->filename = $existingfilename;
  151. $event['existingfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $existingfilename)->out();;
  152. return $event;
  153. } else {
  154. $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
  155. return array(
  156. 'url'=>moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(),
  157. 'id'=>$record->itemid,
  158. 'file'=>$record->filename);
  159. }
  160. }
  161. /**
  162. * Return a upload form
  163. * @return array
  164. */
  165. public function get_listing() {
  166. global $CFG;
  167. $ret = array();
  168. $ret['nologin'] = true;
  169. $ret['nosearch'] = true;
  170. $ret['norefresh'] = true;
  171. $ret['list'] = array();
  172. $ret['dynload'] = false;
  173. $ret['upload'] = array('label'=>get_string('attachment', 'repository'), 'id'=>'repo-form');
  174. return $ret;
  175. }
  176. /**
  177. * supported return types
  178. * @return int
  179. */
  180. public function supported_returntypes() {
  181. return FILE_INTERNAL;
  182. }
  183. }