diff --git a/user/externallib.php b/user/externallib.php index b121c76c0f8..0965198bd84 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -1191,6 +1191,7 @@ class core_user_external extends external_api { * Copy files from a draft area to users private files area. * * @throws invalid_parameter_exception + * @throws moodle_exception * @param int $draftid Id of a draft area containing files. * @return array An array of warnings * @since Moodle 2.6 @@ -1213,6 +1214,15 @@ class core_user_external extends external_api { if (has_capability('moodle/user:ignoreuserquota', $context)) { $maxbytes = USER_CAN_IGNORE_FILE_SIZE_LIMITS; $maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED; + } else { + // Get current used space for this user. + $usedspace = file_get_user_used_space(); + // Get the total size of the new files we want to add to private files. + $newfilesinfo = file_get_draft_area_info($params['draftid']); + + if (($newfilesinfo['filesize_without_references'] + $usedspace) > $maxareabytes) { + throw new moodle_exception('maxareabytes'); + } } $options = array('subdirs' => 1, diff --git a/user/tests/externallib_test.php b/user/tests/externallib_test.php index cbabc9d824b..ba50e073324 100644 --- a/user/tests/externallib_test.php +++ b/user/tests/externallib_test.php @@ -1013,6 +1013,54 @@ class externallib_test extends externallib_advanced_testcase { $this->assertNotEmpty($file); } + + /** + * Test add_user_private_files quota + */ + public function test_add_user_private_files_quota() { + global $USER, $CFG, $DB; + + $this->resetAfterTest(true); + + $context = \context_system::instance(); + $roleid = $this->assignUserCapability('moodle/user:manageownfiles', $context->id); + + $context = \context_user::instance($USER->id); + $contextid = $context->id; + $component = "user"; + $filearea = "draft"; + $itemid = 0; + $filepath = "/"; + $filename = "Simple.txt"; + $filecontent = base64_encode("Let us create a nice simple file"); + $contextlevel = null; + $instanceid = null; + $browser = get_file_browser(); + + // Call the files api to create a file. + $draftfile = core_files_external::upload($contextid, $component, $filearea, $itemid, $filepath, + $filename, $filecontent, $contextlevel, $instanceid); + $draftfile = \external_api::clean_returnvalue(core_files_external::upload_returns(), $draftfile); + $draftid = $draftfile['itemid']; + + // Call the external function to add the file to private files. + core_user_external::add_user_private_files($draftid); + + // Force the quota so we are sure it won't be space to add the new file. + $CFG->userquota = file_get_user_used_space() + 1; + + // Generate a new draftitemid for the same testfile. + $draftfile = core_files_external::upload($contextid, $component, $filearea, $itemid, $filepath, + $filename, $filecontent, $contextlevel, $instanceid); + $draftid = $draftfile['itemid']; + + $this->expectException('moodle_exception'); + $this->expectExceptionMessage(get_string('maxareabytes', 'error')); + + // Call the external function to include the new file. + core_user_external::add_user_private_files($draftid); + } + /** * Test add user device */ diff --git a/user/upgrade.txt b/user/upgrade.txt index 290a5d92d64..9dfbf0aba14 100644 --- a/user/upgrade.txt +++ b/user/upgrade.txt @@ -1,5 +1,9 @@ This files describes API changes for code that uses the user API. +=== 4.1.3 === + +* External function core_user_external::add_user_private_files() now returns moodle_exception when the user quota is exceeded + === 4.1.2 === * New method `core_user::is_current_user`, useful for components implementing permission callbacks for their preferences