Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.
/user/ -> edit.php (source)

Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Allows you to edit a users profile
  19   *
  20   * @copyright 1999 Martin Dougiamas  http://dougiamas.com
  21   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22   * @package core_user
  23   */
  24  
  25  require_once('../config.php');
  26  require_once($CFG->libdir.'/gdlib.php');
  27  require_once($CFG->dirroot.'/user/edit_form.php');
  28  require_once($CFG->dirroot.'/user/editlib.php');
  29  require_once($CFG->dirroot.'/user/profile/lib.php');
  30  require_once($CFG->dirroot.'/user/lib.php');
  31  
  32  $userid = optional_param('id', $USER->id, PARAM_INT);    // User id.
  33  $course = optional_param('course', SITEID, PARAM_INT);   // Course id (defaults to Site).
  34  $returnto = optional_param('returnto', null, PARAM_ALPHA);  // Code determining where to return to after save.
  35  $cancelemailchange = optional_param('cancelemailchange', 0, PARAM_INT);   // Course id (defaults to Site).
  36  
  37  $PAGE->set_url('/user/edit.php', array('course' => $course, 'id' => $userid));
  38  
  39  if (!$course = $DB->get_record('course', array('id' => $course))) {
  40      print_error('invalidcourseid');
  41  }
  42  
  43  if ($course->id != SITEID) {
  44      require_login($course);
  45  } else if (!isloggedin()) {
  46      if (empty($SESSION->wantsurl)) {
  47          $SESSION->wantsurl = $CFG->wwwroot.'/user/edit.php';
  48      }
  49      redirect(get_login_url());
  50  } else {
  51      $PAGE->set_context(context_system::instance());
  52  }
  53  
  54  // Guest can not edit.
  55  if (isguestuser()) {
  56      print_error('guestnoeditprofile');
  57  }
  58  
  59  // The user profile we are editing.
  60  if (!$user = $DB->get_record('user', array('id' => $userid))) {
  61      print_error('invaliduserid');
  62  }
  63  
  64  // Guest can not be edited.
  65  if (isguestuser($user)) {
  66      print_error('guestnoeditprofile');
  67  }
  68  
  69  // User interests separated by commas.
  70  $user->interests = core_tag_tag::get_item_tags_array('core', 'user', $user->id);
  71  
  72  // Remote users cannot be edited. Note we have to perform the strict user_not_fully_set_up() check.
  73  // Otherwise the remote user could end up in endless loop between user/view.php and here.
  74  // Required custom fields are not supported in MNet environment anyway.
  75  if (is_mnet_remote_user($user)) {
  76      if (user_not_fully_set_up($user, true)) {
  77          $hostwwwroot = $DB->get_field('mnet_host', 'wwwroot', array('id' => $user->mnethostid));
  78          print_error('usernotfullysetup', 'mnet', '', $hostwwwroot);
  79      }
  80      redirect($CFG->wwwroot . "/user/view.php?course={$course->id}");
  81  }
  82  
  83  // Load the appropriate auth plugin.
  84  $userauth = get_auth_plugin($user->auth);
  85  
  86  if (!$userauth->can_edit_profile()) {
  87      print_error('noprofileedit', 'auth');
  88  }
  89  
  90  if ($editurl = $userauth->edit_profile_url()) {
  91      // This internal script not used.
  92      redirect($editurl);
  93  }
  94  
  95  if ($course->id == SITEID) {
  96      $coursecontext = context_system::instance();   // SYSTEM context.
  97  } else {
  98      $coursecontext = context_course::instance($course->id);   // Course context.
  99  }
 100  $systemcontext   = context_system::instance();
 101  $personalcontext = context_user::instance($user->id);
 102  
 103  // Check access control.
 104  if ($user->id == $USER->id) {
 105      // Editing own profile - require_login() MUST NOT be used here, it would result in infinite loop!
 106      if (!has_capability('moodle/user:editownprofile', $systemcontext)) {
 107          print_error('cannotedityourprofile');
 108      }
 109  
 110  } else {
 111      // Teachers, parents, etc.
 112      require_capability('moodle/user:editprofile', $personalcontext);
 113      // No editing of guest user account.
 114      if (isguestuser($user->id)) {
 115          print_error('guestnoeditprofileother');
 116      }
 117      // No editing of primary admin!
 118      if (is_siteadmin($user) and !is_siteadmin($USER)) {  // Only admins may edit other admins.
 119          print_error('useradmineditadmin');
 120      }
 121  }
 122  
 123  if ($user->deleted) {
 124      echo $OUTPUT->header();
 125      echo $OUTPUT->heading(get_string('userdeleted'));
 126      echo $OUTPUT->footer();
 127      die;
 128  }
 129  
 130  $PAGE->set_pagelayout('admin');
 131  $PAGE->add_body_class('limitedwidth');
 132  $PAGE->set_context($personalcontext);
 133  if ($USER->id != $user->id) {
 134      $PAGE->navigation->extend_for_user($user);
 135  } else {
 136      if ($node = $PAGE->navigation->find('myprofile', navigation_node::TYPE_ROOTNODE)) {
 137          $node->force_open();
 138      }
 139  }
 140  
 141  // Process email change cancellation.
 142  if ($cancelemailchange) {
 143      cancel_email_update($user->id);
 144  }
 145  
 146  // Load user preferences.
 147  useredit_load_preferences($user);
 148  
 149  // Load custom profile fields data.
 150  profile_load_data($user);
 151  
 152  
 153  // Prepare the editor and create form.
 154  $editoroptions = array(
 155      'maxfiles'   => EDITOR_UNLIMITED_FILES,
 156      'maxbytes'   => $CFG->maxbytes,
 157      'trusttext'  => false,
 158      'forcehttps' => false,
 159      'context'    => $personalcontext
 160  );
 161  
 162  $user = file_prepare_standard_editor($user, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
 163  // Prepare filemanager draft area.
 164  $draftitemid = 0;
 165  $filemanagercontext = $editoroptions['context'];
 166  $filemanageroptions = array('maxbytes'       => $CFG->maxbytes,
 167                               'subdirs'        => 0,
 168                               'maxfiles'       => 1,
 169                               'accepted_types' => 'optimised_image');
 170  file_prepare_draft_area($draftitemid, $filemanagercontext->id, 'user', 'newicon', 0, $filemanageroptions);
 171  $user->imagefile = $draftitemid;
 172  // Create form.
 173  $userform = new user_edit_form(new moodle_url($PAGE->url, array('returnto' => $returnto)), array(
 174      'editoroptions' => $editoroptions,
 175      'filemanageroptions' => $filemanageroptions,
 176      'user' => $user));
 177  
 178  $emailchanged = false;
 179  
 180  // Deciding where to send the user back in most cases.
 181  if ($returnto === 'profile') {
 182      if ($course->id != SITEID) {
 183          $returnurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
 184      } else {
 185          $returnurl = new moodle_url('/user/profile.php', array('id' => $user->id));
 186      }
 187  } else {
 188      $returnurl = new moodle_url('/user/preferences.php', array('userid' => $user->id));
 189  }
 190  
 191  if ($userform->is_cancelled()) {
 192      redirect($returnurl);
 193  } else if ($usernew = $userform->get_data()) {
 194  
 195      $emailchangedhtml = '';
 196  
 197      if ($CFG->emailchangeconfirmation) {
 198          // Users with 'moodle/user:update' can change their email address immediately.
 199          // Other users require a confirmation email.
 200          if (isset($usernew->email) and $user->email != $usernew->email && !has_capability('moodle/user:update', $systemcontext)) {
 201              $a = new stdClass();
 202              $emailchangedkey = random_string(20);
 203              set_user_preference('newemail', $usernew->email, $user->id);
 204              set_user_preference('newemailkey', $emailchangedkey, $user->id);
 205              set_user_preference('newemailattemptsleft', 3, $user->id);
 206  
 207              $a->newemail = $emailchanged = $usernew->email;
 208              $a->oldemail = $usernew->email = $user->email;
 209  
 210              $emailchangedhtml = $OUTPUT->box(get_string('auth_changingemailaddress', 'auth', $a), 'generalbox', 'notice');
 211              $emailchangedhtml .= $OUTPUT->continue_button($returnurl);
 212          }
 213      }
 214  
 215      $authplugin = get_auth_plugin($user->auth);
 216  
 217      $usernew->timemodified = time();
 218  
 219      // Description editor element may not exist!
 220      if (isset($usernew->description_editor) && isset($usernew->description_editor['format'])) {
 221          $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
 222      }
 223  
 224      // Pass a true old $user here.
 225      if (!$authplugin->user_update($user, $usernew)) {
 226          // Auth update failed.
 227          print_error('cannotupdateprofile');
 228      }
 229  
 230      // Update user with new profile data.
 231      user_update_user($usernew, false, false);
 232  
 233      // Update preferences.
 234      useredit_update_user_preference($usernew);
 235  
 236      // Update interests.
 237      if (isset($usernew->interests)) {
 238          useredit_update_interests($usernew, $usernew->interests);
 239      }
 240  
 241      // Update user picture.
 242      if (empty($CFG->disableuserimages)) {
 243          core_user::update_picture($usernew, $filemanageroptions);
 244      }
 245  
 246      // Update mail bounces.
 247      useredit_update_bounces($user, $usernew);
 248  
 249      // Update forum track preference.
 250      useredit_update_trackforums($user, $usernew);
 251  
 252      // Save custom profile fields data.
 253      profile_save_data($usernew);
 254  
 255      // Trigger event.
 256      \core\event\user_updated::create_from_userid($user->id)->trigger();
 257  
 258      // If email was changed and confirmation is required, send confirmation email now to the new address.
 259      if ($emailchanged !== false && $CFG->emailchangeconfirmation) {
 260          $tempuser = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
 261          $tempuser->email = $emailchanged;
 262  
 263          $supportuser = core_user::get_support_user();
 264  
 265          $a = new stdClass();
 266          $a->url = $CFG->wwwroot . '/user/emailupdate.php?key=' . $emailchangedkey . '&id=' . $user->id;
 267          $a->site = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
 268          $a->fullname = fullname($tempuser, true);
 269          $a->supportemail = $supportuser->email;
 270  
 271          $emailupdatemessage = get_string('emailupdatemessage', 'auth', $a);
 272          $emailupdatetitle = get_string('emailupdatetitle', 'auth', $a);
 273  
 274          // Email confirmation directly rather than using messaging so they will definitely get an email.
 275          $noreplyuser = core_user::get_noreply_user();
 276          if (!$mailresults = email_to_user($tempuser, $noreplyuser, $emailupdatetitle, $emailupdatemessage)) {
 277              die("could not send email!");
 278          }
 279      }
 280  
 281      // Reload from db, we need new full name on this page if we do not redirect.
 282      $user = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
 283  
 284      if ($USER->id == $user->id) {
 285          // Override old $USER session variable if needed.
 286          foreach ((array)$user as $variable => $value) {
 287              if ($variable === 'description' or $variable === 'password') {
 288                  // These are not set for security nad perf reasons.
 289                  continue;
 290              }
 291              $USER->$variable = $value;
 292          }
 293          // Preload custom fields.
 294          profile_load_custom_fields($USER);
 295      }
 296  
 297      if (is_siteadmin() and empty($SITE->shortname)) {
 298          // Fresh cli install - we need to finish site settings.
 299          redirect(new moodle_url('/admin/index.php'));
 300      }
 301  
 302      if (!$emailchanged || !$CFG->emailchangeconfirmation) {
 303          redirect($returnurl, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
 304      }
 305  }
 306  
 307  
 308  // Display page header.
 309  $streditmyprofile = get_string('editmyprofile');
 310  $strparticipants  = get_string('participants');
 311  $userfullname     = fullname($user, true);
 312  
 313  $PAGE->set_title("$course->shortname: $streditmyprofile");
 314  $PAGE->set_heading($userfullname);
 315  
 316  echo $OUTPUT->header();
 317  echo $OUTPUT->heading($userfullname);
 318  
 319  if ($emailchanged) {
 320      echo $emailchangedhtml;
 321  } else {
 322      // Finally display THE form.
 323      $userform->display();
 324  }
 325  
 326  // And proper footer.
 327  echo $OUTPUT->footer();