Skip to content

Commit

Permalink
Merge branch 'MDL-58712-master' of git://github.com/jleyva/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
danpoltawski committed Jun 19, 2017
2 parents 6659c5f + f74ac6e commit 6252f44
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 4 deletions.
9 changes: 9 additions & 0 deletions lib/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,15 @@
'type' => 'write',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_user_get_private_files_info' => array(
'classname' => 'core_user_external',
'methodname' => 'get_private_files_info',
'classpath' => 'user/externallib.php',
'description' => 'Returns general information about files in the user private files area.',
'type' => 'read',
'capabilities' => 'moodle/user:manageownfiles',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),

// Competencies functions.
'core_competency_create_competency_framework' => array(
Expand Down
26 changes: 23 additions & 3 deletions lib/filelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -503,9 +503,29 @@ function file_rewrite_pluginfile_urls($text, $file, $contextid, $component, $fil
* (more information will be added as needed).
*/
function file_get_draft_area_info($draftitemid, $filepath = '/') {
global $CFG, $USER;
global $USER;

$usercontext = context_user::instance($USER->id);
return file_get_file_area_info($usercontext->id, 'user', 'draft', $draftitemid, $filepath);
}

/**
* Returns information about files in an area.
*
* @param int $contextid context id
* @param string $component component
* @param string $filearea file area name
* @param int $itemid item id or all files if not specified
* @param string $filepath path to the directory from which the information have to be retrieved.
* @return array with the following entries:
* 'filecount' => number of files in the area.
* 'filesize' => total size of the files in the area.
* 'foldercount' => number of folders in the area.
* 'filesize_without_references' => total size of the area excluding file references.
* @since Moodle 3.4
*/
function file_get_file_area_info($contextid, $component, $filearea, $itemid = false, $filepath = '/') {

$fs = get_file_storage();

$results = array(
Expand All @@ -516,9 +536,9 @@ function file_get_draft_area_info($draftitemid, $filepath = '/') {
);

if ($filepath != '/') {
$draftfiles = $fs->get_directory_files($usercontext->id, 'user', 'draft', $draftitemid, $filepath, true, true);
$draftfiles = $fs->get_directory_files($contextid, $component, $filearea, $itemid, $filepath, true, true);
} else {
$draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id', true);
$draftfiles = $fs->get_area_files($contextid, $component, $filearea, $itemid, 'id', true);
}
foreach ($draftfiles as $file) {
if ($file->is_directory()) {
Expand Down
111 changes: 111 additions & 0 deletions lib/tests/filelib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,117 @@ public function test_file_merge_files_from_draft_area_into_filearea_max_files()
$file = array_shift($files);
$this->assertTrue($file->is_directory());
}

/**
* Test file_get_draft_area_info.
*/
public function test_file_get_draft_area_info() {
global $USER;

$this->resetAfterTest(true);
$this->setAdminUser();
$fs = get_file_storage();

$filerecord = array(
'filename' => 'one.txt',
);
$file = self::create_draft_file($filerecord);
$size = $file->get_filesize();
$draftitemid = $file->get_itemid();
// Add another file.
$filerecord = array(
'itemid' => $draftitemid,
'filename' => 'second.txt',
);
$file = self::create_draft_file($filerecord);
$size += $file->get_filesize();

// Create directory.
$usercontext = context_user::instance($USER->id);
$dir = $fs->create_directory($usercontext->id, 'user', 'draft', $draftitemid, '/testsubdir/');
// Add file to directory.
$filerecord = array(
'itemid' => $draftitemid,
'filename' => 'third.txt',
'filepath' => '/testsubdir/',
);
$file = self::create_draft_file($filerecord);
$size += $file->get_filesize();

$fileinfo = file_get_draft_area_info($draftitemid);
$this->assertEquals(3, $fileinfo['filecount']);
$this->assertEquals($size, $fileinfo['filesize']);
$this->assertEquals(2, $fileinfo['foldercount']); // Base and directory created.
$this->assertEquals($size, $fileinfo['filesize_without_references']);

// Now get files from just one folder.
$fileinfo = file_get_draft_area_info($draftitemid, '/testsubdir/');
$this->assertEquals(1, $fileinfo['filecount']);
$this->assertEquals($file->get_filesize(), $fileinfo['filesize']);
$this->assertEquals(0, $fileinfo['foldercount']); // No subdirectories inside the directory.
$this->assertEquals($file->get_filesize(), $fileinfo['filesize_without_references']);

// Check we get the same results if we call file_get_file_area_info.
$fileinfo = file_get_file_area_info($usercontext->id, 'user', 'draft', $draftitemid);
$this->assertEquals(3, $fileinfo['filecount']);
$this->assertEquals($size, $fileinfo['filesize']);
$this->assertEquals(2, $fileinfo['foldercount']); // Base and directory created.
$this->assertEquals($size, $fileinfo['filesize_without_references']);
}

/**
* Test file_get_file_area_info.
*/
public function test_file_get_file_area_info() {
global $USER;

$this->resetAfterTest(true);
$this->setAdminUser();
$fs = get_file_storage();

$filerecord = array(
'filename' => 'one.txt',
);
$file = self::create_draft_file($filerecord);
$size = $file->get_filesize();
$draftitemid = $file->get_itemid();
// Add another file.
$filerecord = array(
'itemid' => $draftitemid,
'filename' => 'second.txt',
);
$file = self::create_draft_file($filerecord);
$size += $file->get_filesize();

// Create directory.
$usercontext = context_user::instance($USER->id);
$dir = $fs->create_directory($usercontext->id, 'user', 'draft', $draftitemid, '/testsubdir/');
// Add file to directory.
$filerecord = array(
'itemid' => $draftitemid,
'filename' => 'third.txt',
'filepath' => '/testsubdir/',
);
$file = self::create_draft_file($filerecord);
$size += $file->get_filesize();

// Add files to user private file area.
$options = array('subdirs' => 1, 'maxfiles' => 3);
file_merge_files_from_draft_area_into_filearea($draftitemid, $file->get_contextid(), 'user', 'private', 0, $options);

$fileinfo = file_get_file_area_info($usercontext->id, 'user', 'private');
$this->assertEquals(3, $fileinfo['filecount']);
$this->assertEquals($size, $fileinfo['filesize']);
$this->assertEquals(2, $fileinfo['foldercount']); // Base and directory created.
$this->assertEquals($size, $fileinfo['filesize_without_references']);

// Now get files from just one folder.
$fileinfo = file_get_file_area_info($usercontext->id, 'user', 'private', 0, '/testsubdir/');
$this->assertEquals(1, $fileinfo['filecount']);
$this->assertEquals($file->get_filesize(), $fileinfo['filesize']);
$this->assertEquals(0, $fileinfo['foldercount']); // No subdirectories inside the directory.
$this->assertEquals($file->get_filesize(), $fileinfo['filesize_without_references']);
}
}

/**
Expand Down
72 changes: 72 additions & 0 deletions user/externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1860,4 +1860,76 @@ public static function agree_site_policy_returns() {
)
);
}

/**
* Returns description of method parameters.
*
* @return external_function_parameters
* @since Moodle 3.4
*/
public static function get_private_files_info_parameters() {
return new external_function_parameters(
array(
'userid' => new external_value(PARAM_INT, 'Id of the user, default to current user.', VALUE_DEFAULT, 0)
)
);
}

/**
* Returns general information about files in the user private files area.
*
* @param int $userid Id of the user, default to current user.
* @return array of warnings and file area information
* @since Moodle 3.4
* @throws moodle_exception
*/
public static function get_private_files_info($userid = 0) {
global $CFG, $USER;
require_once($CFG->libdir . '/filelib.php');

$params = self::validate_parameters(self::get_private_files_info_parameters(), array('userid' => $userid));
$warnings = array();

$context = context_system::instance();
self::validate_context($context);

if (empty($params['userid']) || $params['userid'] == $USER->id) {
$usercontext = context_user::instance($USER->id);
require_capability('moodle/user:manageownfiles', $usercontext);
} else {
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
core_user::require_active_user($user);
// Only admins can retrieve other users information.
require_capability('moodle/site:config', $context);
$usercontext = context_user::instance($user->id);
}

$fileareainfo = file_get_file_area_info($usercontext->id, 'user', 'private');

$result = array();
$result['filecount'] = $fileareainfo['filecount'];
$result['foldercount'] = $fileareainfo['foldercount'];
$result['filesize'] = $fileareainfo['filesize'];
$result['filesizewithoutreferences'] = $fileareainfo['filesize_without_references'];
$result['warnings'] = $warnings;
return $result;
}

/**
* Returns description of method result value.
*
* @return external_description
* @since Moodle 3.4
*/
public static function get_private_files_info_returns() {
return new external_single_structure(
array(
'filecount' => new external_value(PARAM_INT, 'Number of files in the area.'),
'foldercount' => new external_value(PARAM_INT, 'Number of folders in the area.'),
'filesize' => new external_value(PARAM_INT, 'Total size of the files in the area.'),
'filesizewithoutreferences' => new external_value(PARAM_INT, 'Total size of the area excluding file references'),
'warnings' => new external_warnings()
)
);
}
}
54 changes: 54 additions & 0 deletions user/tests/externallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,60 @@ public function test_agree_site_policy() {
} catch (Exception $e) {
$this->fail('Expecting \'usernotfullysetup\' moodle_exception to be thrown.');
}
}

/**
* Test get_private_files_info
*/
public function test_get_private_files_info() {

$this->resetAfterTest(true);
$user = self::getDataGenerator()->create_user();
$this->setUser($user);
$usercontext = context_user::instance($user->id);

$filerecord = array(
'contextid' => $usercontext->id,
'component' => 'user',
'filearea' => 'private',
'itemid' => 0,
'filepath' => '/',
'filename' => 'thefile',
);

$fs = get_file_storage();
$file = $fs->create_file_from_string($filerecord, 'abc');

// Get my private files information.
$result = core_user_external::get_private_files_info();
$result = external_api::clean_returnvalue(core_user_external::get_private_files_info_returns(), $result);
$this->assertEquals(1, $result['filecount']);
$this->assertEquals($file->get_filesize(), $result['filesize']);
$this->assertEquals(1, $result['foldercount']); // Base directory.
$this->assertEquals($file->get_filesize(), $result['filesizewithoutreferences']);

// As admin, get user information.
$this->setAdminUser();
$result = core_user_external::get_private_files_info($user->id);
$result = external_api::clean_returnvalue(core_user_external::get_private_files_info_returns(), $result);
$this->assertEquals(1, $result['filecount']);
$this->assertEquals($file->get_filesize(), $result['filesize']);
$this->assertEquals(1, $result['foldercount']); // Base directory.
$this->assertEquals($file->get_filesize(), $result['filesizewithoutreferences']);
}

/**
* Test get_private_files_info missing permissions.
*/
public function test_get_private_files_info_missing_permissions() {

$this->resetAfterTest(true);
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$this->setUser($user1);

$this->setExpectedException('required_capability_exception');
// Try to retrieve other user private files info.
core_user_external::get_private_files_info($user2->id);
}
}
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

defined('MOODLE_INTERNAL') || die();

$version = 2017061600.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2017061900.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.

Expand Down

0 comments on commit 6252f44

Please sign in to comment.