Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
/user/ -> edit.php (source)

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

   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->set_context($personalcontext);
 132  if ($USER->id != $user->id) {
 133      $PAGE->navigation->extend_for_user($user);
 134  } else {
 135      if ($node = $PAGE->navigation->find('myprofile', navigation_node::TYPE_ROOTNODE)) {
 136          $node->force_open();
 137      }
 138  }
 139  
 140  // Process email change cancellation.
 141  if ($cancelemailchange) {
 142      cancel_email_update($user->id);
 143  }
 144  
 145  // Load user preferences.
 146  useredit_load_preferences($user);
 147  
 148  // Load custom profile fields data.
 149  profile_load_data($user);
 150  
 151  
 152  // Prepare the editor and create form.
 153  $editoroptions = array(
 154      'maxfiles'   => EDITOR_UNLIMITED_FILES,
 155      'maxbytes'   => $CFG->maxbytes,
 156      'trusttext'  => false,
 157      'forcehttps' => false,
 158      'context'    => $personalcontext
 159  );
 160  
 161  $user = file_prepare_standard_editor($user, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
 162  // Prepare filemanager draft area.
 163  $draftitemid = 0;
 164  $filemanagercontext = $editoroptions['context'];
 165  $filemanageroptions = array('maxbytes'       => $CFG->maxbytes,
 166                               'subdirs'        => 0,
 167                               'maxfiles'       => 1,
 168                               'accepted_types' => 'optimised_image');
 169  file_prepare_draft_area($draftitemid, $filemanagercontext->id, 'user', 'newicon', 0, $filemanageroptions);
 170  $user->imagefile = $draftitemid;
 171  // Create form.
 172  $userform = new user_edit_form(new moodle_url($PAGE->url, array('returnto' => $returnto)), array(
 173      'editoroptions' => $editoroptions,
 174      'filemanageroptions' => $filemanageroptions,
 175      'user' => $user));
 176  
 177  $emailchanged = false;
 178  
 179  // Deciding where to send the user back in most cases.
 180  if ($returnto === 'profile') {
 181      if ($course->id != SITEID) {
 182          $returnurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
 183      } else {
 184          $returnurl = new moodle_url('/user/profile.php', array('id' => $user->id));
 185      }
 186  } else {
 187      $returnurl = new moodle_url('/user/preferences.php', array('userid' => $user->id));
 188  }
 189  
 190  if ($userform->is_cancelled()) {
 191      redirect($returnurl);
 192  } else if ($usernew = $userform->get_data()) {
 193  
 194      $emailchangedhtml = '';
 195  
 196      if ($CFG->emailchangeconfirmation) {
 197          // Users with 'moodle/user:update' can change their email address immediately.
 198          // Other users require a confirmation email.
 199          if (isset($usernew->email) and $user->email != $usernew->email && !has_capability('moodle/user:update', $systemcontext)) {
 200              $a = new stdClass();
 201              $emailchangedkey = random_string(20);
 202              set_user_preference('newemail', $usernew->email, $user->id);
 203              set_user_preference('newemailkey', $emailchangedkey, $user->id);
 204              set_user_preference('newemailattemptsleft', 3, $user->id);
 205  
 206              $a->newemail = $emailchanged = $usernew->email;
 207              $a->oldemail = $usernew->email = $user->email;
 208  
 209              $emailchangedhtml = $OUTPUT->box(get_string('auth_changingemailaddress', 'auth', $a), 'generalbox', 'notice');
 210              $emailchangedhtml .= $OUTPUT->continue_button($returnurl);
 211          }
 212      }
 213  
 214      $authplugin = get_auth_plugin($user->auth);
 215  
 216      $usernew->timemodified = time();
 217  
 218      // Description editor element may not exist!
 219      if (isset($usernew->description_editor) && isset($usernew->description_editor['format'])) {
 220          $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
 221      }
 222  
 223      // Pass a true old $user here.
 224      if (!$authplugin->user_update($user, $usernew)) {
 225          // Auth update failed.
 226          print_error('cannotupdateprofile');
 227      }
 228  
 229      // Update user with new profile data.
 230      user_update_user($usernew, false, false);
 231  
 232      // Update preferences.
 233      useredit_update_user_preference($usernew);
 234  
 235      // Update interests.
 236      if (isset($usernew->interests)) {
 237          useredit_update_interests($usernew, $usernew->interests);
 238      }
 239  
 240      // Update user picture.
 241      if (empty($CFG->disableuserimages)) {
 242          core_user::update_picture($usernew, $filemanageroptions);
 243      }
 244  
 245      // Update mail bounces.
 246      useredit_update_bounces($user, $usernew);
 247  
 248      // Update forum track preference.
 249      useredit_update_trackforums($user, $usernew);
 250  
 251      // Save custom profile fields data.
 252      profile_save_data($usernew);
 253  
 254      // Trigger event.
 255      \core\event\user_updated::create_from_userid($user->id)->trigger();
 256  
 257      // If email was changed and confirmation is required, send confirmation email now to the new address.
 258      if ($emailchanged !== false && $CFG->emailchangeconfirmation) {
 259          $tempuser = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
 260          $tempuser->email = $emailchanged;
 261  
 262          $supportuser = core_user::get_support_user();
 263  
 264          $a = new stdClass();
 265          $a->url = $CFG->wwwroot . '/user/emailupdate.php?key=' . $emailchangedkey . '&id=' . $user->id;
 266          $a->site = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
 267          $a->fullname = fullname($tempuser, true);
 268          $a->supportemail = $supportuser->email;
 269  
 270          $emailupdatemessage = get_string('emailupdatemessage', 'auth', $a);
 271          $emailupdatetitle = get_string('emailupdatetitle', 'auth', $a);
 272  
 273          // Email confirmation directly rather than using messaging so they will definitely get an email.
 274          $noreplyuser = core_user::get_noreply_user();
 275          if (!$mailresults = email_to_user($tempuser, $noreplyuser, $emailupdatetitle, $emailupdatemessage)) {
 276              die("could not send email!");
 277          }
 278      }
 279  
 280      // Reload from db, we need new full name on this page if we do not redirect.
 281      $user = $DB->get_record('user', array('id' => $user->id), '*', MUST_EXIST);
 282  
 283      if ($USER->id == $user->id) {
 284          // Override old $USER session variable if needed.
 285          foreach ((array)$user as $variable => $value) {
 286              if ($variable === 'description' or $variable === 'password') {
 287                  // These are not set for security nad perf reasons.
 288                  continue;
 289              }
 290              $USER->$variable = $value;
 291          }
 292          // Preload custom fields.
 293          profile_load_custom_fields($USER);
 294      }
 295  
 296      if (is_siteadmin() and empty($SITE->shortname)) {
 297          // Fresh cli install - we need to finish site settings.
 298          redirect(new moodle_url('/admin/index.php'));
 299      }
 300  
 301      if (!$emailchanged || !$CFG->emailchangeconfirmation) {
 302          redirect($returnurl, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
 303      }
 304  }
 305  
 306  
 307  // Display page header.
 308  $streditmyprofile = get_string('editmyprofile');
 309  $strparticipants  = get_string('participants');
 310  $userfullname     = fullname($user, true);
 311  
 312  $PAGE->set_title("$course->shortname: $streditmyprofile");
 313  $PAGE->set_heading($userfullname);
 314  
 315  echo $OUTPUT->header();
 316  echo $OUTPUT->heading($userfullname);
 317  
 318  if ($emailchanged) {
 319      echo $emailchangedhtml;
 320  } else {
 321      // Finally display THE form.
 322      $userform->display();
 323  }
 324  
 325  // And proper footer.
 326  echo $OUTPUT->footer();
 327