See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]
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 * Class exposing the api for the cohortroles tool. 19 * 20 * @package tool_cohortroles 21 * @copyright 2015 Damyon Wiese 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace tool_cohortroles; 25 26 use stdClass; 27 use context_system; 28 use core_competency\invalid_persistent_exception; 29 30 /** 31 * Class for doing things with cohort roles. 32 * 33 * @copyright 2015 Damyon Wiese 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 class api { 37 38 /** 39 * Create a cohort role assignment from a record containing all the data for the class. 40 * 41 * Requires moodle/role:manage capability at the system context. 42 * 43 * @param stdClass $record Record containing all the data for an instance of the class. 44 * @return competency 45 */ 46 public static function create_cohort_role_assignment(stdClass $record) { 47 $cohortroleassignment = new cohort_role_assignment(0, $record); 48 $context = context_system::instance(); 49 50 // First we do a permissions check. 51 require_capability('moodle/role:manage', $context); 52 53 // Validate before we check for existing records. 54 if (!$cohortroleassignment->is_valid()) { 55 throw new invalid_persistent_exception($cohortroleassignment->get_errors()); 56 } 57 58 $existing = cohort_role_assignment::get_record((array) $record); 59 if (!empty($existing)) { 60 return false; 61 } else { 62 // OK - all set. 63 $cohortroleassignment->create(); 64 } 65 return $cohortroleassignment; 66 } 67 68 /** 69 * Delete a cohort role assignment by id. 70 * 71 * Requires moodle/role:manage capability at the system context. 72 * 73 * @param int $id The record to delete. This will also remove this role from the user for all users in the system. 74 * @return boolean 75 */ 76 public static function delete_cohort_role_assignment($id) { 77 $cohortroleassignment = new cohort_role_assignment($id); 78 $context = context_system::instance(); 79 80 // First we do a permissions check. 81 require_capability('moodle/role:manage', $context); 82 83 // OK - all set. 84 return $cohortroleassignment->delete(); 85 } 86 87 /** 88 * Perform a search based on the provided filters and return a paginated list of records. 89 * 90 * Requires moodle/role:manage capability at the system context. 91 * 92 * @param string $sort The column to sort on 93 * @param string $order ('ASC' or 'DESC') 94 * @param int $skip Number of records to skip (pagination) 95 * @param int $limit Max of records to return (pagination) 96 * @return array of cohort_role_assignment 97 */ 98 public static function list_cohort_role_assignments($sort = '', $order = 'ASC', $skip = 0, $limit = 0) { 99 $context = context_system::instance(); 100 101 // First we do a permissions check. 102 require_capability('moodle/role:manage', $context); 103 104 // OK - all set. 105 return cohort_role_assignment::get_records(array(), $sort, $order, $skip, $limit); 106 } 107 108 /** 109 * Perform a search based on the provided filters and return a paginated list of records. 110 * 111 * Requires moodle/role:manage capability at system context. 112 * 113 * @return int 114 */ 115 public static function count_cohort_role_assignments() { 116 $context = context_system::instance(); 117 118 // First we do a permissions check. 119 require_capability('moodle/role:manage', $context); 120 121 // OK - all set. 122 return cohort_role_assignment::count_records(); 123 } 124 125 /** 126 * Sync all roles - adding and deleting role assignments as required. 127 * 128 * Slow. Should only be called from a background task. 129 * 130 * Requires moodle/role:manage capability at the system context. 131 * 132 * @return array('rolesadded' => array of (useridassignedto, useridassignedover, roleid), 133 * 'rolesremoved' => array of (useridassignedto, useridassignedover, roleid)) 134 */ 135 public static function sync_all_cohort_roles() { 136 global $DB; 137 138 $context = context_system::instance(); 139 140 // First we do a permissions check. 141 require_capability('moodle/role:manage', $context); 142 143 // Ok ready to go. 144 $rolesadded = array(); 145 $rolesremoved = array(); 146 147 // Remove any cohort role mappings for roles which have been deleted. 148 // The role assignments are not a consideration because these will have been removed when the role was. 149 $DB->delete_records_select('tool_cohortroles', "roleid NOT IN (SELECT id FROM {role})"); 150 151 // Get all cohort role assignments and group them by user and role. 152 $all = cohort_role_assignment::get_records(array(), 'userid, roleid'); 153 // We build an better structure to loop on. 154 $info = array(); 155 foreach ($all as $cra) { 156 if (!isset($info[$cra->get('userid')])) { 157 $info[$cra->get('userid')] = array(); 158 } 159 if (!isset($info[$cra->get('userid')][$cra->get('roleid')])) { 160 $info[$cra->get('userid')][$cra->get('roleid')] = array(); 161 } 162 array_push($info[$cra->get('userid')][$cra->get('roleid')], $cra->get('cohortid')); 163 } 164 // Then for each user+role combo - find user context in the cohort without a role assigned. 165 166 foreach ($info as $userid => $roles) { 167 foreach ($roles as $roleid => $cohorts) { 168 list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED); 169 170 $params['usercontext'] = CONTEXT_USER; 171 $params['roleid'] = $roleid; 172 $params['userid'] = $userid; 173 174 $sql = 'SELECT DISTINCT u.id AS userid, ra.id, ctx.id AS contextid 175 FROM {user} u 176 JOIN {cohort_members} cm ON u.id = cm.userid 177 JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext 178 LEFT JOIN {role_assignments} ra ON ra.contextid = ctx.id 179 AND ra.roleid = :roleid 180 AND ra.userid = :userid 181 WHERE cm.cohortid ' . $cohortsql . ' 182 AND u.deleted = 0 183 AND ra.id IS NULL'; 184 185 $toadd = $DB->get_records_sql($sql, $params); 186 187 foreach ($toadd as $add) { 188 role_assign($roleid, $userid, $add->contextid, 'tool_cohortroles'); 189 $rolesadded[] = array( 190 'useridassignedto' => $userid, 191 'useridassignedover' => $add->userid, 192 'roleid' => $roleid 193 ); 194 } 195 } 196 } 197 198 // And for each user+role combo - find user context not in the cohort with a role assigned. 199 // If the role was assigned by this component, unassign the role. 200 foreach ($info as $userid => $roles) { 201 foreach ($roles as $roleid => $cohorts) { 202 // Now we are looking for entries NOT in the cohort. 203 list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED); 204 205 $params['usercontext'] = CONTEXT_USER; 206 $params['roleid'] = $roleid; 207 $params['userid'] = $userid; 208 $params['component'] = 'tool_cohortroles'; 209 210 $sql = 'SELECT u.id as userid, ra.id, ctx.id AS contextid 211 FROM {user} u 212 JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext 213 JOIN {role_assignments} ra ON ra.contextid = ctx.id AND ra.roleid = :roleid AND ra.userid = :userid 214 LEFT JOIN {cohort_members} cm ON u.id = cm.userid 215 AND cm.cohortid ' . $cohortsql . ' 216 WHERE ra.component = :component AND cm.cohortid IS NULL'; 217 218 $toremove = $DB->get_records_sql($sql, $params); 219 foreach ($toremove as $remove) { 220 role_unassign($roleid, $userid, $remove->contextid, 'tool_cohortroles'); 221 $rolesremoved[] = array( 222 'useridassignedto' => $userid, 223 'useridassignedover' => $remove->userid, 224 'roleid' => $roleid 225 ); 226 } 227 } 228 } 229 230 // Clean the legacy role assignments which are stale. 231 $paramsclean['usercontext'] = CONTEXT_USER; 232 $paramsclean['component'] = 'tool_cohortroles'; 233 $sql = 'SELECT DISTINCT(ra.id), ra.roleid, ra.userid, ra.contextid, ctx.instanceid 234 FROM {role_assignments} ra 235 JOIN {context} ctx ON ctx.id = ra.contextid AND ctx.contextlevel = :usercontext 236 JOIN {cohort_members} cm ON cm.userid = ctx.instanceid 237 LEFT JOIN {tool_cohortroles} tc ON tc.cohortid = cm.cohortid 238 AND tc.userid = ra.userid 239 AND tc.roleid = ra.roleid 240 WHERE ra.component = :component 241 AND tc.id is null'; 242 if ($candidatelegacyassignments = $DB->get_records_sql($sql, $paramsclean)) { 243 $sql = 'SELECT DISTINCT(ra.id) 244 FROM {role_assignments} ra 245 JOIN {context} ctx ON ctx.id = ra.contextid AND ctx.contextlevel = :usercontext 246 JOIN {cohort_members} cm ON cm.userid = ctx.instanceid 247 JOIN {tool_cohortroles} tc ON tc.cohortid = cm.cohortid AND tc.userid = ra.userid 248 WHERE ra.component = :component'; 249 if ($currentvalidroleassignments = $DB->get_records_sql($sql, $paramsclean)) { 250 foreach ($candidatelegacyassignments as $candidate) { 251 if (!array_key_exists($candidate->id, $currentvalidroleassignments)) { 252 role_unassign($candidate->roleid, $candidate->userid, $candidate->contextid, 'tool_cohortroles'); 253 $rolesremoved[] = array( 254 'useridassignedto' => $candidate->userid, 255 'useridassignedover' => $candidate->instanceid, 256 'roleid' => $candidate->roleid 257 ); 258 } 259 } 260 } else { 261 foreach ($candidatelegacyassignments as $candidate) { 262 role_unassign($candidate->roleid, $candidate->userid, $candidate->contextid, 'tool_cohortroles'); 263 $rolesremoved[] = array( 264 'useridassignedto' => $candidate->userid, 265 'useridassignedover' => $candidate->instanceid, 266 'roleid' => $candidate->roleid 267 ); 268 } 269 } 270 } 271 272 return array('rolesadded' => $rolesadded, 'rolesremoved' => $rolesremoved); 273 } 274 275 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body