MDL-51789 users: Allow picture update from webservices.

useredit_update_picture as moved to user_update_picture
as it's more general.  It was also moved to user/lib.php
so it can be used by both webservices and edit without more include files.
This commit is contained in:
Russell Smith
2016-06-21 16:36:53 +10:00
parent 49619ce243
commit 5407c5b0f4
6 changed files with 125 additions and 52 deletions
+61
View File
@@ -278,6 +278,67 @@ class core_user {
}
}
/**
* Updates the provided users profile picture based upon the expected fields returned from the edit or edit_advanced forms.
*
* @param stdClass $usernew An object that contains some information about the user being updated
* @param array $filemanageroptions
* @return bool True if the user was updated, false if it stayed the same.
*/
public static function update_picture(stdClass $usernew, $filemanageroptions = array()) {
global $CFG, $DB;
require_once("$CFG->libdir/gdlib.php");
$context = context_user::instance($usernew->id, MUST_EXIST);
$user = core_user::get_user($usernew->id, 'id, picture', MUST_EXIST);
$newpicture = $user->picture;
// Get file_storage to process files.
$fs = get_file_storage();
if (!empty($usernew->deletepicture)) {
// The user has chosen to delete the selected users picture.
$fs->delete_area_files($context->id, 'user', 'icon'); // Drop all images in area.
$newpicture = 0;
} else {
// Save newly uploaded file, this will avoid context mismatch for newly created users.
file_save_draft_area_files($usernew->imagefile, $context->id, 'user', 'newicon', 0, $filemanageroptions);
if (($iconfiles = $fs->get_area_files($context->id, 'user', 'newicon')) && count($iconfiles) == 2) {
// Get file which was uploaded in draft area.
foreach ($iconfiles as $file) {
if (!$file->is_directory()) {
break;
}
}
// Copy file to temporary location and the send it for processing icon.
if ($iconfile = $file->copy_content_to_temp()) {
// There is a new image that has been uploaded.
// Process the new image and set the user to make use of it.
// NOTE: Uploaded images always take over Gravatar.
$newpicture = (int)process_new_icon($context, 'user', 'icon', 0, $iconfile);
// Delete temporary file.
@unlink($iconfile);
// Remove uploaded file.
$fs->delete_area_files($context->id, 'user', 'newicon');
} else {
// Something went wrong while creating temp file.
// Remove uploaded file.
$fs->delete_area_files($context->id, 'user', 'newicon');
return false;
}
}
}
if ($newpicture != $user->picture) {
$DB->set_field('user', 'picture', $newpicture, array('id' => $user->id));
return true;
} else {
return false;
}
}
/**
* Definition of user profile fields and the expected parameter type for data validation.
*
+1 -1
View File
@@ -236,7 +236,7 @@ if ($usernew = $userform->get_data()) {
// Update user picture.
if (empty($CFG->disableuserimages)) {
useredit_update_picture($usernew, $userform, $filemanageroptions);
core_user::update_picture($usernew, $filemanageroptions);
}
// Update mail bounces.
+1 -1
View File
@@ -239,7 +239,7 @@ if ($usernew = $userform->get_data()) {
// Update user picture.
if (empty($USER->newadminuser)) {
useredit_update_picture($usernew, $userform, $filemanageroptions);
core_user::update_picture($usernew, $filemanageroptions);
}
// Update mail bounces.
+7 -50
View File
@@ -164,62 +164,19 @@ function useredit_update_user_preference($usernew) {
/**
* Updates the provided users profile picture based upon the expected fields returned from the edit or edit_advanced forms.
*
* @deprecated since Moodle 3.2 MDL-51789 - please use core_user::update_picture() instead.
* @todo MDL-54858 This will be deleted in Moodle 3.5.
* @see core_user::update_picture()
*
* @global moodle_database $DB
* @param stdClass $usernew An object that contains some information about the user being updated
* @param moodleform $userform The form that was submitted to edit the form
* @param moodleform $userform The form that was submitted to edit the form (unused)
* @param array $filemanageroptions
* @return bool True if the user was updated, false if it stayed the same.
*/
function useredit_update_picture(stdClass $usernew, moodleform $userform, $filemanageroptions = array()) {
global $CFG, $DB;
require_once("$CFG->libdir/gdlib.php");
$context = context_user::instance($usernew->id, MUST_EXIST);
$user = $DB->get_record('user', array('id' => $usernew->id), 'id, picture', MUST_EXIST);
$newpicture = $user->picture;
// Get file_storage to process files.
$fs = get_file_storage();
if (!empty($usernew->deletepicture)) {
// The user has chosen to delete the selected users picture.
$fs->delete_area_files($context->id, 'user', 'icon'); // Drop all images in area.
$newpicture = 0;
} else {
// Save newly uploaded file, this will avoid context mismatch for newly created users.
file_save_draft_area_files($usernew->imagefile, $context->id, 'user', 'newicon', 0, $filemanageroptions);
if (($iconfiles = $fs->get_area_files($context->id, 'user', 'newicon')) && count($iconfiles) == 2) {
// Get file which was uploaded in draft area.
foreach ($iconfiles as $file) {
if (!$file->is_directory()) {
break;
}
}
// Copy file to temporary location and the send it for processing icon.
if ($iconfile = $file->copy_content_to_temp()) {
// There is a new image that has been uploaded.
// Process the new image and set the user to make use of it.
// NOTE: Uploaded images always take over Gravatar.
$newpicture = (int)process_new_icon($context, 'user', 'icon', 0, $iconfile);
// Delete temporary file.
@unlink($iconfile);
// Remove uploaded file.
$fs->delete_area_files($context->id, 'user', 'newicon');
} else {
// Something went wrong while creating temp file.
// Remove uploaded file.
$fs->delete_area_files($context->id, 'user', 'newicon');
return false;
}
}
}
if ($newpicture != $user->picture) {
$DB->set_field('user', 'picture', $newpicture, array('id' => $user->id));
return true;
} else {
return false;
}
debugging('useredit_update_picture() is deprecated. Please use core_user::update_picture() instead.', DEBUG_DEVELOPER);
return core_user::update_picture($usernew, $filemanageroptions);
}
/**
+24
View File
@@ -386,6 +386,9 @@ class core_user_external extends external_api {
new external_value(core_user::get_property_type('middlename'), 'The middle name of the user', VALUE_OPTIONAL),
'alternatename' =>
new external_value(core_user::get_property_type('alternatename'), 'The alternate name of the user', VALUE_OPTIONAL),
'userpicture' =>
new external_value(PARAM_INT, 'The itemid where the new user picture '.
'has been uploaded to, 0 to delete', VALUE_OPTIONAL),
'customfields' => new external_multiple_structure(
new external_single_structure(
array(
@@ -426,10 +429,31 @@ class core_user_external extends external_api {
$params = self::validate_parameters(self::update_users_parameters(), array('users' => $users));
$filemanageroptions = array('maxbytes' => $CFG->maxbytes,
'subdirs' => 0,
'maxfiles' => 1,
'accepted_types' => 'web_image');
$transaction = $DB->start_delegated_transaction();
foreach ($params['users'] as $user) {
user_update_user($user, true, false);
// Update user picture if it was specified for this user.
if (empty($CFG->disableuserimages) && isset($user['userpicture'])) {
$userobject = (object)$user;
$userobject->deletepicture = null;
if ($user['userpicture'] == 0) {
$userobject->deletepicture = true;
} else {
$userobject->imagefile = $user['userpicture'];
}
core_user::update_picture($userobject, $filemanageroptions);
}
// Update user custom fields.
if (!empty($user['customfields'])) {
+31
View File
@@ -566,6 +566,22 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
$this->resetAfterTest(true);
$wsuser = self::getDataGenerator()->create_user();
self::setUser($wsuser);
$context = context_user::instance($USER->id);
$contextid = $context->id;
$filename = "reddot.png";
$filecontent = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38"
. "GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
// Call the files api to create a file.
$draftfile = core_files_external::upload($contextid, 'user', 'draft', 0, '/',
$filename, $filecontent, null, null);
$draftfile = external_api::clean_returnvalue(core_files_external::upload_returns(), $draftfile);
$draftid = $draftfile['itemid'];
$user1 = self::getDataGenerator()->create_user();
$user1 = array(
@@ -582,6 +598,7 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
'email' => '[email protected]',
'description' => 'This is a description for user 1',
'city' => 'Perth',
'userpicture' => $draftid,
'country' => 'AU'
);
@@ -600,6 +617,20 @@ class core_user_externallib_testcase extends externallib_advanced_testcase {
$this->assertEquals($dbuser->description, $user1['description']);
$this->assertEquals($dbuser->city, $user1['city']);
$this->assertEquals($dbuser->country, $user1['country']);
$this->assertNotEquals(0, $dbuser->picture, 'Picture must be set to the new icon itemid for this user');
// Confirm no picture change when parameter is not supplied.
unset($user1['userpicture']);
core_user_external::update_users(array($user1));
$dbusernopic = $DB->get_record('user', array('id' => $user1['id']));
$this->assertEquals($dbuser->picture, $dbusernopic->picture, 'Picture not change without the parameter.');
// Confirm delete of picture deletes the picture from the user record.
$user1['userpicture'] = 0;
core_user_external::update_users(array($user1));
$dbuserdelpic = $DB->get_record('user', array('id' => $user1['id']));
$this->assertEquals(0, $dbuserdelpic->picture, 'Picture must be deleted when sent as 0.');
// Call without required capability.
$this->unassignUserCapability('moodle/user:update', $context->id, $roleid);