diff --git a/admin/settings/security.php b/admin/settings/security.php index b83198bbffb..e067ecdf273 100644 --- a/admin/settings/security.php +++ b/admin/settings/security.php @@ -21,11 +21,17 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page get_string('profileroles','admin'), get_string('configprofileroles', 'admin'), array('student', 'teacher', 'editingteacher'))); - + $max_upload_choices = get_max_upload_sizes(); // maxbytes set to 0 will allow the maxium server lmit for uploads $max_upload_choices[0] = get_string('serverlimit', 'admin'); $temp->add(new admin_setting_configselect('maxbytes', get_string('maxbytes', 'admin'), get_string('configmaxbytes', 'admin'), 0, $max_upload_choices)); + // 100MB + $defaultuserquota = 104857600; + $params = new stdclass; + $params->bytes = $defaultuserquota; + $params->displaysize = display_size($defaultuserquota); + $temp->add(new admin_setting_configtext('userquota', get_string('userquota', 'admin'), get_string('configuserquota', 'admin', $params), $defaultuserquota)); $temp->add(new admin_setting_configcheckbox('allowobjectembed', get_string('allowobjectembed', 'admin'), get_string('configallowobjectembed', 'admin'), 0)); $temp->add(new admin_setting_configcheckbox('enabletrusttext', get_string('enabletrusttext', 'admin'), get_string('configenabletrusttext', 'admin'), 0)); @@ -77,7 +83,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page // "modulesecurity" settingpage $temp = new admin_settingpage('modulesecurity', get_string('modulesecurity', 'admin')); $temp->add(new admin_setting_configselect('restrictmodulesfor', get_string('restrictmodulesfor', 'admin'), get_string('configrestrictmodulesfor', 'admin'), 'none', array('none' => get_string('nocourses'), - 'all' => get_string('fulllistofcourses'), + 'all' => get_string('fulllistofcourses'), 'requested' => get_string('requestedcourses')))); $temp->add(new admin_setting_configcheckbox('restrictbydefault', get_string('restrictbydefault', 'admin'), get_string('configrestrictbydefault', 'admin'), 0)); if (!$options = $DB->get_records('modules')) { diff --git a/lang/en/admin.php b/lang/en/admin.php index dabbaae7f23..d4f04d7267b 100755 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -303,6 +303,7 @@ $string['configrestrictbydefault'] = 'Should new courses that are created that f $string['configrestrictmodulesfor'] = 'Which courses should have the setting for disabling some activity modules? Note that this setting only applies to teachers, administrators will still be able to add any activity to a course.'; $string['configrunclamavonupload'] = 'When enabled, clam AV will be used to scan all uploaded files.'; $string['configrunclamonupload'] = 'Run clam AV on file upload? You will need a correct path in pathtoclam for this to work. (Clam AV is a free virus scanner that you can get from http://www.clamav.net/)'; +$string['configuserquota'] = 'The maxbytes if files that user can use in user area, the value is in bytes. {$a->bytes} bytes == {$a->displaysize}'; $string['configsectioninterface'] = 'Interface'; $string['configsectionmail'] = 'Mail'; $string['configsectionmaintenance'] = 'Maintenance'; @@ -983,6 +984,7 @@ $string['usersrenamed'] = 'Users renamed'; $string['usersskipped'] = 'Users skipped'; $string['usersupdated'] = 'Users updated'; $string['usersweakpassword'] = 'Users having a weak password'; +$string['userquota'] = 'User quota'; $string['usetags'] = 'Enable tags functionality'; $string['uubulk'] = 'Select for bulk operations'; $string['uubulkall'] = 'All users'; diff --git a/lang/en/error.php b/lang/en/error.php index 08afe1bb3f9..c894dd2caf5 100755 --- a/lang/en/error.php +++ b/lang/en/error.php @@ -494,6 +494,7 @@ $string['usernotrenamedoff'] = 'User not renamed - renaming not allowed'; $string['usernotupdatedadmin'] = 'Cannot update admin accounts'; $string['usernotupdatederror'] = 'User not updated - error'; $string['usernotupdatednotexists'] = 'User not updated - does not exist'; +$string['userquotalimit'] = 'You have reached your file quota limit.'; $string['userselectortoomany'] = 'user_selector got more than one selected user, even though multiselect is false.'; $string['wrongcall'] = 'This script is called wrongly'; $string['wrongcontextid'] = 'Context ID was incorrect (cannot find it)'; diff --git a/lib/filelib.php b/lib/filelib.php index e4ee837a11f..be696ff518d 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -499,6 +499,35 @@ function file_get_user_area_info($draftitemid, $filearea = 'user_draft') { return $results; } +/** + * Get used space of files + * @return int totalbytes + */ +function file_get_user_used_space() { + global $DB, $CFG, $USER; + + $usercontext = get_context_instance(CONTEXT_USER, $USER->id); + $fs = get_file_storage(); + + // only count files in user context + $conditions = array('contextid'=>$usercontext->id); + + $totalbytes = 0; + $files = array(); + $file_records = $DB->get_records('files', $conditions); + foreach ($file_records as $file_record) { + if ($file_record->filename === '.') { + continue; + } + // doesn't count same files + if (!isset($files[$file_record->contenthash])) { + $totalbytes += $file_record->filesize; + } else { + $files[$file_record->contenthash] = true; + } + } + return (int)$totalbytes; +} /** * Convert any string to a valid filepath @@ -845,7 +874,7 @@ function format_postdata_for_curlcall($postdata) { $currentdata = urlencode($k); format_array_postdata_for_curlcall($v, $currentdata, $data); } else { - $data[] = urlencode($k).'='.urlencode($v); + $data[] = urlencode($k).'='.urlencode($v); } } $convertedpostdata = implode('&', $data); @@ -927,7 +956,7 @@ function download_file_content($url, $headers=null, $postdata=null, $fullrespons curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); } - + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout); diff --git a/repository/lib.php b/repository/lib.php index 32e209f6f2b..936b1e67fdf 100644 --- a/repository/lib.php +++ b/repository/lib.php @@ -528,7 +528,7 @@ abstract class repository { } if ($records = $DB->get_records('repository',$params,'sortorder')) { foreach($records as $type) { - if (file_exists($CFG->dirroot . '/repository/'. $type->type .'/repository.class.php')) { + if (file_exists($CFG->dirroot . '/repository/'. $type->type .'/repository.class.php')) { $types[] = new repository_type($type->type, (array)get_config($type->type), $type->visible, $type->sortorder); } } @@ -1805,7 +1805,7 @@ function initialise_filepicker($args) { $repositories = repository::get_instances(array( 'context'=>array($user_context, get_system_context()), 'currentcontext'=> $context, - 'accepted_types'=>$args->accepted_types, + 'accepted_types'=>$args->accepted_types, 'return_types'=>$args->return_types )); diff --git a/repository/repository_ajax.php b/repository/repository_ajax.php index 3f4321449c4..dbddc4943b0 100755 --- a/repository/repository_ajax.php +++ b/repository/repository_ajax.php @@ -59,8 +59,10 @@ header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); $err = new stdclass; $err->client_id = $client_id; -if ($maxbytes == 0) { - $maxbytes = get_max_upload_file_size(); +$moodle_maxbytes = get_max_upload_file_size(); +// to prevent maxbytes greater than moodle maxbytes setting +if ($maxbytes == 0 || $maxbytes>=$moodle_maxbytes) { + $maxbytes = $moodle_maxbytes; } /// Check permissions @@ -221,9 +223,10 @@ switch ($action) { break; case 'download': try { - // we have two special repoisitory type need to deal with + // We have two special repoisitory type need to deal with + // local and recent plugins don't added new files to moodle, just add new records to database + // so we don't check user quota and maxbytes here if ($repo->options['type'] == 'local' || $repo->options['type'] == 'recent' ) { - // saveas_filearea try { $fileinfo = $repo->copy_to_area($source, $saveas_filearea, $itemid, $saveas_path, $saveas_filename); } catch (Exception $e) { @@ -250,11 +253,13 @@ switch ($action) { // allow external links in url element all the time $allowexternallink = ($allowexternallink || ($env == 'url')); + // Use link of the files if ($allowexternallink and $linkexternal === 'yes' and ($repo->supported_returntypes() || FILE_EXTERNAL)) { // use external link try { $link = $repo->get_link($source); } catch (repository_exception $e){ + throw $e; } $info = array(); $info['filename'] = $saveas_filename; @@ -263,16 +268,24 @@ switch ($action) { echo json_encode($info); die; } else { - // get the file location + // Download file to moodle $file = $repo->get_file($source, $saveas_filename); if ($file['path'] === false) { $err->e = get_string('cannotdownload', 'repository'); die(json_encode($err)); } + + // check if exceed maxbytes if (($maxbytes!==-1) && (filesize($file['path']) > $maxbytes)) { throw new file_exception('maxbytes'); } + // check if exceed user quota + $userquota = file_get_user_used_space(); + if (filesize($file['path'])+$userquota>=(int)$CFG->userquota) { + throw new file_exception('userquotalimit'); + } + $record = new stdclass; $record->filepath = $saveas_path; $record->filename = $saveas_filename; @@ -299,9 +312,6 @@ switch ($action) { die; } } - } catch (repository_exception $e){ - $err->e = $e->getMessage(); - die(json_encode($err)); } catch (Exception $e) { $err->e = $e->getMessage(); die(json_encode($err)); diff --git a/repository/upload/repository.class.php b/repository/upload/repository.class.php index c92e0869459..8e0f362d8bd 100755 --- a/repository/upload/repository.class.php +++ b/repository/upload/repository.class.php @@ -116,7 +116,7 @@ class repository_upload extends repository { * @return mixed stored_file object or false if error; may throw exception if duplicate found */ public function upload_to_filepool($elname, $record, $override = true) { - global $USER; + global $USER, $CFG; $context = get_context_instance(CONTEXT_USER, $USER->id); $fs = get_file_storage(); $browser = get_file_browser(); @@ -138,6 +138,11 @@ class repository_upload extends repository { $record->filename = $_FILES[$elname]['name']; } + $userquota = file_get_user_used_space(); + if (filesize($_FILES[$elname]['tmp_name'])+$userquota>=(int)$CFG->userquota) { + throw new file_exception('userquotalimit'); + } + if (empty($record->itemid)) { $record->itemid = 0; } diff --git a/version.php b/version.php index 8dbf2f53a3e..f9931dddf52 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2010050411; // YYYYMMDD = date of the last version bump + $version = 2010050412; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 Preview 1 (Build: 20100511)'; // Human-friendly version name