Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [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   * User roles report list all the users who have been assigned a particular
  19   * role in all contexts.
  20   *
  21   * @package    core_role
  22   * @copyright  &copy; 2007 The Open University and others
  23   * @author     t.j.hunt@open.ac.uk and others
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  require_once(__DIR__ . '/../../config.php');
  28  
  29  // Get params.
  30  $userid = required_param('userid', PARAM_INT);
  31  $courseid = required_param('courseid', PARAM_INT);
  32  
  33  // Validate them and get the corresponding objects.
  34  $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
  35  $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
  36  
  37  $usercontext = context_user::instance($user->id);
  38  $coursecontext = context_course::instance($course->id);
  39  $systemcontext = context_system::instance();
  40  
  41  $baseurl = new moodle_url('/admin/roles/usersroles.php', array('userid'=>$userid, 'courseid'=>$courseid));
  42  
  43  $PAGE->set_url($baseurl);
  44  $PAGE->set_pagelayout('admin');
  45  
  46  // Check login and permissions.
  47  if ($course->id == SITEID) {
  48      require_login(null, false);
  49      $PAGE->set_context($usercontext);
  50  } else {
  51      require_login($course);
  52      $PAGE->set_context($coursecontext);
  53  }
  54  
  55  $canview = has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
  56          'moodle/role:override', 'moodle/role:manage'), $usercontext);
  57  if (!$canview) {
  58      throw new \moodle_exception('nopermissions', 'error', '', get_string('checkpermissions', 'core_role'));
  59  }
  60  
  61  if ($userid != $USER->id) {
  62      // If its not the current user we need to extend the navigation for that user to ensure
  63      // their navigation is loaded and this page found upon it.
  64      $PAGE->navigation->extend_for_user($user);
  65  }
  66  if ($course->id != $SITE->id || $userid != $USER->id) {
  67      // If we're within a course OR if we're viewing another user then we need to include the
  68      // settings base on the navigation to ensure that the navbar will contain the users name.
  69      $PAGE->navbar->includesettingsbase = true;
  70  }
  71  
  72  // Now get the role assignments for this user.
  73  $sql = "SELECT ra.id, ra.userid, ra.contextid, ra.roleid, ra.component, ra.itemid, c.path
  74            FROM {role_assignments} ra
  75            JOIN {context} c ON ra.contextid = c.id
  76            JOIN {role} r ON ra.roleid = r.id
  77           WHERE ra.userid = ?
  78        ORDER BY contextlevel DESC, contextid ASC, r.sortorder ASC";
  79  $roleassignments = $DB->get_records_sql($sql, array($user->id));
  80  
  81  $allroles = role_fix_names(get_all_roles());
  82  
  83  // In order to display a nice tree of contexts, we need to get all the
  84  // ancestors of all the contexts in the query we just did.
  85  $requiredcontexts = array();
  86  foreach ($roleassignments as $ra) {
  87      $requiredcontexts = array_merge($requiredcontexts, explode('/', trim($ra->path, '/')));
  88  }
  89  $requiredcontexts = array_unique($requiredcontexts);
  90  
  91  // Now load those contexts.
  92  if ($requiredcontexts) {
  93      list($sqlcontexttest, $contextparams) = $DB->get_in_or_equal($requiredcontexts);
  94      $contexts = get_sorted_contexts('ctx.id ' . $sqlcontexttest, $contextparams);
  95  } else {
  96      $contexts = array();
  97  }
  98  
  99  // Prepare some empty arrays to hold the data we are about to compute.
 100  foreach ($contexts as $conid => $con) {
 101      $contexts[$conid]->children = array();
 102      $contexts[$conid]->roleassignments = array();
 103  }
 104  
 105  // Put the contexts into a tree structure.
 106  foreach ($contexts as $conid => $con) {
 107      $context = context::instance_by_id($conid);
 108      $parentcontext = $context->get_parent_context();
 109      if ($parentcontext) {
 110          $contexts[$parentcontext->id]->children[] = $conid;
 111      }
 112  }
 113  
 114  // Put the role capabilities into the context tree.
 115  foreach ($roleassignments as $ra) {
 116      $contexts[$ra->contextid]->roleassignments[$ra->roleid] = $ra;
 117  }
 118  
 119  $assignableroles = get_assignable_roles($usercontext, ROLENAME_BOTH);
 120  $overridableroles = get_overridable_roles($usercontext, ROLENAME_BOTH);
 121  
 122  // Print the header.
 123  $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $coursecontext));
 124  $straction = get_string('thisusersroles', 'core_role');
 125  $title = get_string('xroleassignments', 'core_role', $fullname);
 126  
 127  // Course header.
 128  $PAGE->set_title($title);
 129  if ($courseid == SITEID) {
 130      $PAGE->set_heading($fullname);
 131  } else {
 132      $PAGE->set_heading($course->fullname.': '.$fullname);
 133  }
 134  echo $OUTPUT->header();
 135  echo $OUTPUT->heading($title);
 136  echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal');
 137  
 138  // Display them.
 139  if (!$roleassignments) {
 140      echo '<p>', get_string('noroleassignments', 'core_role'), '</p>';
 141  } else {
 142      print_report_tree($systemcontext->id, $contexts, $systemcontext, $fullname, $allroles);
 143  }
 144  
 145  // End of page.
 146  echo $OUTPUT->box_end();
 147  echo $OUTPUT->footer();
 148  
 149  function print_report_tree($contextid, $contexts, $systemcontext, $fullname, $allroles) {
 150      global $CFG, $OUTPUT;
 151  
 152      // Only compute lang strings, etc once.
 153      static $stredit = null, $strcheckpermissions, $globalroleassigner, $assignurl, $checkurl;
 154      if (is_null($stredit)) {
 155          $stredit = get_string('edit');
 156          $strcheckpermissions = get_string('checkpermissions', 'core_role');
 157          $globalroleassigner = has_capability('moodle/role:assign', $systemcontext);
 158          $assignurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/assign.php';
 159          $checkurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/check.php';
 160      }
 161  
 162      // Pull the current context into an array for convenience.
 163      $context = context::instance_by_id($contextid);
 164  
 165      // Print the context name.
 166      echo $OUTPUT->heading(html_writer::link($context->get_url(), $context->get_context_name()),
 167              4, 'contextname');
 168  
 169      // If there are any role assignments here, print them.
 170      foreach ($contexts[$contextid]->roleassignments as $ra) {
 171          $role = $allroles[$ra->roleid];
 172  
 173          $value = $ra->contextid . ',' . $ra->roleid;
 174          $inputid = 'unassign' . $value;
 175  
 176          echo '<p>';
 177          echo $role->localname;
 178          if (has_capability('moodle/role:assign', $context)) {
 179              $raurl = $assignurl . '?contextid=' . $ra->contextid . '&amp;roleid=' .
 180                      $ra->roleid . '&amp;removeselect[]=' . $ra->userid;
 181              $churl = $checkurl . '?contextid=' . $ra->contextid . '&amp;reportuser=' . $ra->userid;
 182              if ($context->contextlevel == CONTEXT_USER) {
 183                  $raurl .= '&amp;userid=' . $context->instanceid;
 184                  $churl .= '&amp;userid=' . $context->instanceid;
 185              }
 186              $a = new stdClass;
 187              $a->fullname = $fullname;
 188              $a->contextlevel = $context->get_level_name();
 189              if ($context->contextlevel == CONTEXT_SYSTEM) {
 190                  $strgoto = get_string('gotoassignsystemroles', 'core_role');
 191                  $strcheck = get_string('checksystempermissionsfor', 'core_role', $a);
 192              } else {
 193                  $strgoto = get_string('gotoassignroles', 'core_role', $a);
 194                  $strcheck = get_string('checkuserspermissionshere', 'core_role', $a);
 195              }
 196              echo ' <a title="' . $strgoto . '" href="' . $raurl . '">' . $OUTPUT->pix_icon('t/edit', $stredit) . '</a> ';
 197              echo ' <a title="' . $strcheck . '" href="' . $churl . '">' . $OUTPUT->pix_icon('t/preview', $strcheckpermissions) . '</a> ';
 198              echo "</p>\n";
 199          }
 200      }
 201  
 202      // If there are any child contexts, print them recursively.
 203      if (!empty($contexts[$contextid]->children)) {
 204          echo '<ul>';
 205          foreach ($contexts[$contextid]->children as $childcontextid) {
 206              echo '<li>';
 207              print_report_tree($childcontextid, $contexts, $systemcontext, $fullname, $allroles);
 208              echo '</li>';
 209          }
 210          echo '</ul>';
 211      }
 212  }