From a08171c5c2c1a48ea5fc6e5c1b6fe9503437c9e0 Mon Sep 17 00:00:00 2001 From: skodak Date: Tue, 28 Apr 2009 19:08:33 +0000 Subject: [PATCH] MDL-19002 file upload limits support --- course/editsection.php | 2 +- course/modedit.php | 4 +- lib/filelib.php | 112 ++++++++++++++++++++++++++++------------- mod/forum/lib.php | 8 +-- mod/glossary/edit.php | 4 +- 5 files changed, 85 insertions(+), 45 deletions(-) diff --git a/course/editsection.php b/course/editsection.php index 2f08c1e1a7..400cb54785 100644 --- a/course/editsection.php +++ b/course/editsection.php @@ -33,7 +33,7 @@ } else if ($data = $mform->get_data()) { - $text = file_save_draft_area_files($data->summary['itemid'], $context->id, 'course_section', $section->id, true, $data->summary['text']); + $text = file_save_draft_area_files($data->summary['itemid'], $context->id, 'course_section', $section->id, array('subdirs'=>true), $data->summary['text']); $DB->set_field("course_sections", "summary", $text, array("id"=>$section->id)); add_to_log($course->id, "course", "editsection", "editsection.php?id=$section->id", "$section->section"); redirect("view.php?id=$course->id"); diff --git a/course/modedit.php b/course/modedit.php index b3fd4e06b0..0c8c6adc81 100644 --- a/course/modedit.php +++ b/course/modedit.php @@ -325,7 +325,7 @@ if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) { $fromform->intro = file_save_draft_area_files($fromform->introeditor['itemid'], $modcontext->id, $fromform->modulename.'_intro', 0, - true, $fromform->introeditor['text']); + array('subdirs'=>true), $fromform->introeditor['text']); $fromform->introformat = $fromform->introeditor['format']; unset($fromform->introeditor); } @@ -397,7 +397,7 @@ if (plugin_supports('mod', $fromform->modulename, FEATURE_MOD_INTRO, true)) { $fromform->intro = file_save_draft_area_files($fromform->introeditor['itemid'], $modcontext->id, $fromform->modulename.'_intro', 0, - true, $fromform->introeditor['text']); + array('subdirs'=>true), $fromform->introeditor['text']); $fromform->introformat = $fromform->introeditor['format']; unset($fromform->introeditor); } diff --git a/lib/filelib.php b/lib/filelib.php index a61c41fc98..35a4c94d67 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -248,20 +248,31 @@ function file_get_submitted_draft_itemid($elname) { * @param int $draftitemid the id of the draft area to use. Normally obtained * from file_get_submitted_draft_itemid('elementname') or similar. * @param integer $contextid This parameter and the next two identify the file area to save to. - * @param string $filearea helps indentify the file area. - * @param integer $itemid helps identify the file area. - * @param boolean $subdirs allow directory structure within the file area. + * @param string $filearea indentifies the file area. + * @param integer $itemid helps identifies the file area. + * @param array $optionss area options (subdirs=>false, maxfiles=-1, maxbytes=0) * @param string $text some html content that needs to have embedded links rewritten * to the @@PLUGINFILE@@ form for saving in the database. * @param boolean $forcehttps force https urls. * @return string if $text was passed in, the rewritten $text is returned. Otherwise NULL. */ -function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid, $subdirs=false, $text=null, $forcehttps=false) { +function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid, array $options=null, $text=null, $forcehttps=false) { global $CFG, $USER; $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); + $options = (array)$options; + if (!isset($options['subdirs'])) { + $options['subdirs'] = false; + } + if (!isset($options['maxfiles'])) { + $options['maxfiles'] = -1; // unlimited + } + if (!isset($options['maxbytes'])) { + $options['maxbytes'] = 0; // unlimited + } + $draftfiles = $fs->get_area_files($usercontext->id, 'user_draft', $draftitemid, 'id'); $oldfiles = $fs->get_area_files($contextid, $filearea, $itemid, 'id'); @@ -270,43 +281,72 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid $fs->delete_area_files($contextid, $filearea, $itemid); } else if (count($oldfiles) < 2) { + $filecount = 0; // there were no files before - one file means root dir only ;-) - $fs->delete_area_files($contextid, $filearea, $itemid); $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); foreach ($draftfiles as $file) { - if (!$subdirs and $file->get_filepath() !== '/') { + if (!$options['subdirs']) { + if ($file->get_filepath() !== '/' or $file->is_directory()) { + continue; + } + } + if ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize()) { + // oversized file - should not get here at all continue; } + if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) { + // more files - should not get here at all + break; + } + if (!$file->is_directory()) { + $filecount++; + } $fs->create_file_from_storedfile($file_record, $file); } } else { // we have to merge old and new files - we want to keep file ids for files that were not changed $file_record = array('contextid'=>$contextid, 'filearea'=>$filearea, 'itemid'=>$itemid); + + $newhashes = array(); foreach ($draftfiles as $file) { - if (!$subdirs and $file->get_filepath() !== '/') { - continue; - } $newhash = sha1($contextid.$filearea.$itemid.$file->get_filepath().$file->get_filename()); - if (isset($oldfiles[$newhash])) { - $oldfile = $oldfiles[$newhash]; - unset($oldfiles[$newhash]); // do not delete afterwards - + $newhashes[$newhash] = $file; + } + $filecount = 0; + foreach ($oldfiles as $file) { + $oldhash = $file->get_pathnamehash(); + if (isset($newhashes[$oldhash])) { if (!$file->is_directory()) { - if ($file->get_contenthash() === $oldfile->get_contenthash()) { - // file was not changed at all - continue; - } else { - // file changed, delete the original - $oldfile->delete(); - } + $filecount++; } + // unchanged file already there + unset($newhashes[$oldhash]); + } else { + // delete files not needed any more + $file->delete(); } - $fs->create_file_from_storedfile($file_record, $file); } - // cleanup deleted files and dirs - foreach ($oldfiles as $file) { - $file->delete(); + + // now add new files + foreach ($newhashes as $file) { + if (!$options['subdirs']) { + if ($file->get_filepath() !== '/' or $file->is_directory()) { + continue; + } + } + if ($options['maxbytes'] and $options['maxbytes'] < $file->get_filesize()) { + // oversized file - should not get here at all + continue; + } + if ($options['maxfiles'] != -1 and $options['maxfiles'] <= $filecount) { + // more files - should not get here at all + break; + } + if (!$file->is_directory()) { + $filecount++; + } + $fs->create_file_from_storedfile($file_record, $file); } } @@ -339,28 +379,28 @@ function file_save_draft_area_files($draftitemid, $contextid, $filearea, $itemid * @return error description string, '' if ok */ function file_get_upload_error($errorcode) { - + switch ($errorcode) { case 0: // UPLOAD_ERR_OK - no error $errmessage = ''; break; - + case 1: // UPLOAD_ERR_INI_SIZE $errmessage = get_string('uploadserverlimit'); break; - + case 2: // UPLOAD_ERR_FORM_SIZE $errmessage = get_string('uploadformlimit'); break; - + case 3: // UPLOAD_ERR_PARTIAL $errmessage = get_string('uploadpartialfile'); break; - + case 4: // UPLOAD_ERR_NO_FILE $errmessage = get_string('uploadnofilefound'); break; - + // Note: there is no error with a value of 5 case 6: // UPLOAD_ERR_NO_TMP_DIR @@ -2059,7 +2099,7 @@ class curl_cache { $this->ttl = $CFG->curlcache; } } - + /** * TODO Document */ @@ -2081,7 +2121,7 @@ class curl_cache { } return false; } - + /** * TODO Document */ @@ -2092,7 +2132,7 @@ class curl_cache { fwrite($fp, serialize($val)); fclose($fp); } - + /** * TODO Document */ @@ -2141,7 +2181,7 @@ class file_type_to_ext { $this->tree = array(); $this->result = array(); } - + /** * TODO Document */ @@ -2160,7 +2200,7 @@ class file_type_to_ext { $this->tree[] = $key; } } - + /** * TODO Document */ @@ -2174,7 +2214,7 @@ class file_type_to_ext { } } - + /** * TODO Document */ diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 101f1d6c72..242d07c270 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -4126,7 +4126,7 @@ function forum_add_attachment($post, $forum, $cm, $mform=null, &$message=null) { $info = file_get_draft_area_info($post->attachments); $present = ($info['filecount']>0) ? '1' : ''; - file_save_draft_area_files($post->attachments, $context->id, 'forum_attachment', $post->id, false); + file_save_draft_area_files($post->attachments, $context->id, 'forum_attachment', $post->id); $DB->set_field('forum_posts', 'attachment', $present, array('id'=>$post->id)); @@ -4153,7 +4153,7 @@ function forum_add_new_post($post, $mform, &$message) { if (! $post->id = $DB->insert_record("forum_posts", $post)) { return false; } - $message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, true, $message); + $message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $message); $DB->set_field('forum_posts', 'message', $message, array('id'=>$post->id)); forum_add_attachment($post, $forum, $cm, $mform, $message); @@ -4193,7 +4193,7 @@ function forum_update_post($post, $mform, &$message) { $discussion->timestart = $post->timestart; $discussion->timeend = $post->timeend; } - $post->message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, true, $post->message); + $post->message = file_save_draft_area_files($post->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $post->message); $DB->set_field('forum_posts', 'message', $post->message, array('id'=>$post->id)); if (!$DB->update_record('forum_discussions', $discussion)) { @@ -4245,7 +4245,7 @@ function forum_add_discussion($discussion, $mform=null, &$message=null) { return 0; } - $text = file_save_draft_area_files($discussion->itemid, $context->id, 'forum_post', $post->id, true, $post->message); + $text = file_save_draft_area_files($discussion->itemid, $context->id, 'forum_post', $post->id, array('subdirs'=>true), $post->message); $DB->set_field('forum_posts', 'message', $text, array('id'=>$post->id)); // Now do the main entry for the discussion, linking to this first post diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index 05fc497459..fedfa06ba0 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -126,12 +126,12 @@ if ($mform->is_cancelled()){ // save and relink embedded images $entry->definitionformat = $data->entry['format']; - $entry->definition = file_save_draft_area_files($draftid_editor, $context->id, 'glossary_entry', $entry->id, true, $data->entry['text']); + $entry->definition = file_save_draft_area_files($draftid_editor, $context->id, 'glossary_entry', $entry->id, array('subdirs'=>true), $data->entry['text']); // save attachments $info = file_get_draft_area_info($draftitemid); $entry->attachment = ($info['filecount']>0) ? '1' : ''; - file_save_draft_area_files($draftitemid, $context->id, 'glossary_attachment', $entry->id, false); + file_save_draft_area_files($draftitemid, $context->id, 'glossary_attachment', $entry->id); // store the final values $DB->update_record('glossary_entries', $entry); -- 2.39.5