Beispiel #1
0
 /**
  * Do the actual processing of the uploaded file
  * @param string $saveas_filename name to give to the file
  * @param int $maxbytes maximum file size
  * @param mixed $types optional array of file extensions that are allowed or '*' for all
  * @param string $savepath optional path to save the file to
  * @param int $itemid optional the ID for this item within the file area
  * @param string $license optional the license to use for this file
  * @param string $author optional the name of the author of this file
  * @param bool $overwriteexisting optional user has asked to overwrite the existing file
  * @param int $areamaxbytes maximum size of the file area.
  * @return object containing details of the file uploaded
  */
 public function process_upload($saveas_filename, $maxbytes, $types = '*', $savepath = '/', $itemid = 0, $license = null, $author = '', $overwriteexisting = false, $areamaxbytes = FILE_AREA_MAX_BYTES_UNLIMITED)
 {
     global $USER, $CFG;
     if (is_array($types) and in_array('*', $types) or $types == '*') {
         $this->mimetypes = '*';
     } else {
         foreach ($types as $type) {
             $this->mimetypes[] = mimeinfo('type', $type);
         }
     }
     if ($license == null) {
         $license = $CFG->sitedefaultlicense;
     }
     $record = new stdClass();
     $record->filearea = 'draft';
     $record->component = 'user';
     $record->filepath = $savepath;
     $record->itemid = $itemid;
     $record->license = $license;
     $record->author = $author;
     $context = context_user::instance($USER->id);
     $elname = 'repo_upload_file';
     $fs = get_file_storage();
     $sm = get_string_manager();
     if ($record->filepath !== '/') {
         $record->filepath = file_correct_filepath($record->filepath);
     }
     if (!isset($_FILES[$elname])) {
         throw new moodle_exception('nofile');
     }
     if (!empty($_FILES[$elname]['error'])) {
         switch ($_FILES[$elname]['error']) {
             case UPLOAD_ERR_INI_SIZE:
                 throw new moodle_exception('upload_error_ini_size', 'repository_upload');
                 break;
             case UPLOAD_ERR_FORM_SIZE:
                 throw new moodle_exception('upload_error_form_size', 'repository_upload');
                 break;
             case UPLOAD_ERR_PARTIAL:
                 throw new moodle_exception('upload_error_partial', 'repository_upload');
                 break;
             case UPLOAD_ERR_NO_FILE:
                 throw new moodle_exception('upload_error_no_file', 'repository_upload');
                 break;
             case UPLOAD_ERR_NO_TMP_DIR:
                 throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
                 break;
             case UPLOAD_ERR_CANT_WRITE:
                 throw new moodle_exception('upload_error_cant_write', 'repository_upload');
                 break;
             case UPLOAD_ERR_EXTENSION:
                 throw new moodle_exception('upload_error_extension', 'repository_upload');
                 break;
             default:
                 throw new moodle_exception('nofile');
         }
     }
     \core\antivirus\manager::scan_file($_FILES[$elname]['tmp_name'], $_FILES[$elname]['name'], true);
     // {@link repository::build_source_field()}
     $sourcefield = $this->get_file_source_info($_FILES[$elname]['name']);
     $record->source = self::build_source_field($sourcefield);
     if (empty($saveas_filename)) {
         $record->filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
     } else {
         $ext = '';
         $match = array();
         $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE);
         if (strpos($filename, '.') === false) {
             // File has no extension at all - do not add a dot.
             $record->filename = $saveas_filename;
         } else {
             if (preg_match('/\\.([a-z0-9]+)$/i', $filename, $match)) {
                 if (isset($match[1])) {
                     $ext = $match[1];
                 }
             }
             $ext = !empty($ext) ? $ext : '';
             if (preg_match('#\\.(' . $ext . ')$#i', $saveas_filename)) {
                 // saveas filename contains file extension already
                 $record->filename = $saveas_filename;
             } else {
                 $record->filename = $saveas_filename . '.' . $ext;
             }
         }
     }
     // Check the file has some non-null contents - usually an indication that a user has
     // tried to upload a folder by mistake
     if (!$this->check_valid_contents($_FILES[$elname]['tmp_name'])) {
         throw new moodle_exception('upload_error_invalid_file', 'repository_upload', '', $record->filename);
     }
     if ($this->mimetypes != '*') {
         // check filetype
         $filemimetype = file_storage::mimetype($_FILES[$elname]['tmp_name'], $record->filename);
         if (!in_array($filemimetype, $this->mimetypes)) {
             throw new moodle_exception('invalidfiletype', 'repository', '', get_mimetype_description(array('filename' => $_FILES[$elname]['name'])));
         }
     }
     if (empty($record->itemid)) {
         $record->itemid = 0;
     }
     if ($maxbytes !== -1 && filesize($_FILES[$elname]['tmp_name']) > $maxbytes) {
         $maxbytesdisplay = display_size($maxbytes);
         throw new file_exception('maxbytesfile', (object) array('file' => $record->filename, 'size' => $maxbytesdisplay));
     }
     if (file_is_draft_area_limit_reached($record->itemid, $areamaxbytes, filesize($_FILES[$elname]['tmp_name']))) {
         throw new file_exception('maxareabytes');
     }
     $record->contextid = $context->id;
     $record->userid = $USER->id;
     if (repository::draftfile_exists($record->itemid, $record->filepath, $record->filename)) {
         $existingfilename = $record->filename;
         $unused_filename = repository::get_unused_filename($record->itemid, $record->filepath, $record->filename);
         $record->filename = $unused_filename;
         $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
         if ($overwriteexisting) {
             repository::overwrite_existing_draftfile($record->itemid, $record->filepath, $existingfilename, $record->filepath, $record->filename);
             $record->filename = $existingfilename;
         } else {
             $event = array();
             $event['event'] = 'fileexists';
             $event['newfile'] = new stdClass();
             $event['newfile']->filepath = $record->filepath;
             $event['newfile']->filename = $unused_filename;
             $event['newfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $unused_filename)->out(false);
             $event['existingfile'] = new stdClass();
             $event['existingfile']->filepath = $record->filepath;
             $event['existingfile']->filename = $existingfilename;
             $event['existingfile']->url = moodle_url::make_draftfile_url($record->itemid, $record->filepath, $existingfilename)->out(false);
             return $event;
         }
     } else {
         $stored_file = $fs->create_file_from_pathname($record, $_FILES[$elname]['tmp_name']);
     }
     return array('url' => moodle_url::make_draftfile_url($record->itemid, $record->filepath, $record->filename)->out(false), 'id' => $record->itemid, 'file' => $record->filename);
 }
        }
        break;
    case 'upload':
        // handle exception here instead moodle default exception handler
        // see MDL-23407
        try {
            // TODO: add file scanning MDL-19380 into each plugin
            $result = $repo->upload($saveas_filename, $maxbytes);
            echo json_encode($result);
        } catch (Exception $e) {
            $err->error = $e->getMessage();
            echo json_encode($err);
            die;
        }
        break;
    case 'overwrite':
        // existing file
        $filepath = required_param('existingfilepath', PARAM_PATH);
        $filename = required_param('existingfilename', PARAM_FILE);
        // user added file which needs to replace the existing file
        $newfilepath = required_param('newfilepath', PARAM_PATH);
        $newfilename = required_param('newfilename', PARAM_FILE);
        echo json_encode(repository::overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename));
        break;
    case 'deletetmpfile':
        // delete tmp file
        $newfilepath = required_param('newfilepath', PARAM_PATH);
        $newfilename = required_param('newfilename', PARAM_FILE);
        echo json_encode(repository::delete_tempfile_from_draft($itemid, $newfilepath, $newfilename));
        break;
}
Beispiel #3
0
                    $info = repository::move_to_filepool($downloadedfile['path'], $record);
                    if (empty($info)) {
                        $info['e'] = get_string('error', 'moodle');
                    }
                }
            }
            echo json_encode($info);
            die;
        }
        break;
    case 'upload':
        $result = $repo->upload($saveas_filename, $maxbytes);
        echo json_encode($result);
        break;
    case 'overwrite':
        // existing file
        $filepath = required_param('existingfilepath', PARAM_PATH);
        $filename = required_param('existingfilename', PARAM_FILE);
        // user added file which needs to replace the existing file
        $newfilepath = required_param('newfilepath', PARAM_PATH);
        $newfilename = required_param('newfilename', PARAM_FILE);
        $info = repository::overwrite_existing_draftfile($itemid, $filepath, $filename, $newfilepath, $newfilename);
        echo json_encode($info);
        break;
    case 'deletetmpfile':
        // delete tmp file
        $newfilepath = required_param('newfilepath', PARAM_PATH);
        $newfilename = required_param('newfilename', PARAM_FILE);
        echo json_encode(repository::delete_tempfile_from_draft($itemid, $newfilepath, $newfilename));
        break;
}
Beispiel #4
0
 // Extract archive and move all files from $temppath to $filepath
 if ($file->extract_to_storage($zipper, $user_context->id, 'user', 'draft', $draftid, $temppath, $USER->id) !== false) {
     $extractedfiles = $fs->get_directory_files($user_context->id, 'user', 'draft', $draftid, $temppath, true);
     $xtemppath = preg_quote($temppath, '|');
     foreach ($extractedfiles as $file) {
         $realpath = preg_replace('|^'.$xtemppath.'|', $filepath, $file->get_filepath());
         if (!$file->is_directory()) {
             // Set the source to the extracted file to indicate that it came from archive.
             $file->set_source(serialize((object)array('source' => $filepath)));
         }
         if (!$fs->file_exists($user_context->id, 'user', 'draft', $draftid, $realpath, $file->get_filename())) {
             // File or directory did not exist, just move it.
             $file->rename($realpath, $file->get_filename());
         } else if (!$file->is_directory()) {
             // File already existed, overwrite it
             repository::overwrite_existing_draftfile($draftid, $realpath, $file->get_filename(), $file->get_filepath(), $file->get_filename());
         } else {
             // Directory already existed, remove temporary dir but make sure we don't remove the existing dir
             $doremovedirs[] = $file->get_filepath();
             $donotremovedirs[] = $realpath;
         }
     }
     $return = new stdClass();
     $return->filepath = $filepath;
 } else {
     $return = false;
 }
 // Remove remaining temporary directories.
 foreach (array_diff($doremovedirs, $donotremovedirs) as $filepath) {
     if ($file = $fs->get_file($user_context->id, 'user', 'draft', $draftid, $filepath, '.')) {
         $file->delete();