You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
8.8 KiB
228 lines
8.8 KiB
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* Class exposing the api for the cohortroles tool.
|
|
*
|
|
* @package tool_cohortroles
|
|
* @copyright 2015 Damyon Wiese
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
namespace tool_cohortroles;
|
|
|
|
use stdClass;
|
|
use context_system;
|
|
use core_competency\invalid_persistent_exception;
|
|
|
|
/**
|
|
* Class for doing things with cohort roles.
|
|
*
|
|
* @copyright 2015 Damyon Wiese
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class api {
|
|
|
|
/**
|
|
* Create a cohort role assignment from a record containing all the data for the class.
|
|
*
|
|
* Requires moodle/role:manage capability at the system context.
|
|
*
|
|
* @param stdClass $record Record containing all the data for an instance of the class.
|
|
* @return competency
|
|
*/
|
|
public static function create_cohort_role_assignment(stdClass $record) {
|
|
$cohortroleassignment = new cohort_role_assignment(0, $record);
|
|
$context = context_system::instance();
|
|
|
|
// First we do a permissions check.
|
|
require_capability('moodle/role:manage', $context);
|
|
|
|
// Validate before we check for existing records.
|
|
if (!$cohortroleassignment->is_valid()) {
|
|
throw new invalid_persistent_exception($cohortroleassignment->get_errors());
|
|
}
|
|
|
|
$existing = cohort_role_assignment::get_record((array) $record);
|
|
if (!empty($existing)) {
|
|
return false;
|
|
} else {
|
|
// OK - all set.
|
|
$cohortroleassignment->create();
|
|
}
|
|
return $cohortroleassignment;
|
|
}
|
|
|
|
/**
|
|
* Delete a cohort role assignment by id.
|
|
*
|
|
* Requires moodle/role:manage capability at the system context.
|
|
*
|
|
* @param int $id The record to delete. This will also remove this role from the user for all users in the system.
|
|
* @return boolean
|
|
*/
|
|
public static function delete_cohort_role_assignment($id) {
|
|
$cohortroleassignment = new cohort_role_assignment($id);
|
|
$context = context_system::instance();
|
|
|
|
// First we do a permissions check.
|
|
require_capability('moodle/role:manage', $context);
|
|
|
|
// OK - all set.
|
|
return $cohortroleassignment->delete();
|
|
}
|
|
|
|
/**
|
|
* Perform a search based on the provided filters and return a paginated list of records.
|
|
*
|
|
* Requires moodle/role:manage capability at the system context.
|
|
*
|
|
* @param string $sort The column to sort on
|
|
* @param string $order ('ASC' or 'DESC')
|
|
* @param int $skip Number of records to skip (pagination)
|
|
* @param int $limit Max of records to return (pagination)
|
|
* @return array of cohort_role_assignment
|
|
*/
|
|
public static function list_cohort_role_assignments($sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
|
|
$context = context_system::instance();
|
|
|
|
// First we do a permissions check.
|
|
require_capability('moodle/role:manage', $context);
|
|
|
|
// OK - all set.
|
|
return cohort_role_assignment::get_records(array(), $sort, $order, $skip, $limit);
|
|
}
|
|
|
|
/**
|
|
* Perform a search based on the provided filters and return a paginated list of records.
|
|
*
|
|
* Requires moodle/role:manage capability at system context.
|
|
*
|
|
* @return int
|
|
*/
|
|
public static function count_cohort_role_assignments() {
|
|
$context = context_system::instance();
|
|
|
|
// First we do a permissions check.
|
|
require_capability('moodle/role:manage', $context);
|
|
|
|
// OK - all set.
|
|
return cohort_role_assignment::count_records();
|
|
}
|
|
|
|
/**
|
|
* Sync all roles - adding and deleting role assignments as required.
|
|
*
|
|
* Slow. Should only be called from a background task.
|
|
*
|
|
* Requires moodle/role:manage capability at the system context.
|
|
*
|
|
* @return array('rolesadded' => array of (useridassignedto, useridassignedover, roleid),
|
|
* 'rolesremoved' => array of (useridassignedto, useridassignedover, roleid))
|
|
*/
|
|
public static function sync_all_cohort_roles() {
|
|
global $DB;
|
|
|
|
$context = context_system::instance();
|
|
|
|
// First we do a permissions check.
|
|
require_capability('moodle/role:manage', $context);
|
|
|
|
// Ok ready to go.
|
|
$rolesadded = array();
|
|
$rolesremoved = array();
|
|
|
|
// Get all cohort role assignments and group them by user and role.
|
|
$all = cohort_role_assignment::get_records(array(), 'userid, roleid');
|
|
// We build an better structure to loop on.
|
|
$info = array();
|
|
foreach ($all as $cra) {
|
|
if (!isset($info[$cra->get('userid')])) {
|
|
$info[$cra->get('userid')] = array();
|
|
}
|
|
if (!isset($info[$cra->get('userid')][$cra->get('roleid')])) {
|
|
$info[$cra->get('userid')][$cra->get('roleid')] = array();
|
|
}
|
|
array_push($info[$cra->get('userid')][$cra->get('roleid')], $cra->get('cohortid'));
|
|
}
|
|
// Then for each user+role combo - find user context in the cohort without a role assigned.
|
|
|
|
foreach ($info as $userid => $roles) {
|
|
foreach ($roles as $roleid => $cohorts) {
|
|
list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED);
|
|
|
|
$params['usercontext'] = CONTEXT_USER;
|
|
$params['roleid'] = $roleid;
|
|
$params['userid'] = $userid;
|
|
|
|
$sql = 'SELECT DISTINCT u.id AS userid, ra.id, ctx.id AS contextid
|
|
FROM {user} u
|
|
JOIN {cohort_members} cm ON u.id = cm.userid
|
|
JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext
|
|
LEFT JOIN {role_assignments} ra ON ra.contextid = ctx.id
|
|
AND ra.roleid = :roleid
|
|
AND ra.userid = :userid
|
|
WHERE cm.cohortid ' . $cohortsql . '
|
|
AND ra.id IS NULL';
|
|
|
|
$toadd = $DB->get_records_sql($sql, $params);
|
|
|
|
foreach ($toadd as $add) {
|
|
role_assign($roleid, $userid, $add->contextid, 'tool_cohortroles');
|
|
$rolesadded[] = array(
|
|
'useridassignedto' => $userid,
|
|
'useridassignedover' => $add->userid,
|
|
'roleid' => $roleid
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// And for each user+role combo - find user context not in the cohort with a role assigned.
|
|
// If the role was assigned by this component, unassign the role.
|
|
foreach ($info as $userid => $roles) {
|
|
foreach ($roles as $roleid => $cohorts) {
|
|
// Now we are looking for entries NOT in the cohort.
|
|
list($cohortsql, $params) = $DB->get_in_or_equal($cohorts, SQL_PARAMS_NAMED);
|
|
|
|
$params['usercontext'] = CONTEXT_USER;
|
|
$params['roleid'] = $roleid;
|
|
$params['userid'] = $userid;
|
|
$params['component'] = 'tool_cohortroles';
|
|
|
|
$sql = 'SELECT u.id as userid, ra.id, ctx.id AS contextid
|
|
FROM {user} u
|
|
JOIN {context} ctx ON u.id = ctx.instanceid AND ctx.contextlevel = :usercontext
|
|
JOIN {role_assignments} ra ON ra.contextid = ctx.id AND ra.roleid = :roleid AND ra.userid = :userid
|
|
LEFT JOIN {cohort_members} cm ON u.id = cm.userid
|
|
AND cm.cohortid ' . $cohortsql . '
|
|
WHERE ra.component = :component AND cm.cohortid IS NULL';
|
|
|
|
$toremove = $DB->get_records_sql($sql, $params);
|
|
foreach ($toremove as $remove) {
|
|
role_unassign($roleid, $userid, $remove->contextid, 'tool_cohortroles');
|
|
$rolesremoved[] = array(
|
|
'useridassignedto' => $userid,
|
|
'useridassignedover' => $remove->userid,
|
|
'roleid' => $roleid
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return array('rolesadded' => $rolesadded, 'rolesremoved' => $rolesremoved);
|
|
}
|
|
|
|
}
|
|
|