mirror of
https://github.com/moodle/moodle.git
synced 2025-01-29 11:46:19 +01:00
MDL-80504 forum: Fix seperate group mode
This commit is contained in:
parent
fba3e87a24
commit
1c059cb3fe
@ -629,6 +629,7 @@ class core_enrol_external extends external_api {
|
||||
'searchanywhere' => new external_value(PARAM_BOOL, 'find a match anywhere, or only at the beginning'),
|
||||
'page' => new external_value(PARAM_INT, 'Page number'),
|
||||
'perpage' => new external_value(PARAM_INT, 'Number per page'),
|
||||
'contextid' => new external_value(PARAM_INT, 'Context ID', VALUE_DEFAULT, null),
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -641,11 +642,12 @@ class core_enrol_external extends external_api {
|
||||
* @param bool $searchanywhere Match anywhere in the string
|
||||
* @param int $page Page number
|
||||
* @param int $perpage Max per page
|
||||
* @param ?int $contextid Context ID we are in - we might use search on activity level and its group mode can be different from course group mode.
|
||||
* @return array An array of users
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function search_users(int $courseid, string $search, bool $searchanywhere, int $page, int $perpage): array {
|
||||
global $PAGE, $DB, $CFG;
|
||||
public static function search_users(int $courseid, string $search, bool $searchanywhere, int $page, int $perpage, ?int $contextid = null): array {
|
||||
global $PAGE, $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/enrol/locallib.php');
|
||||
require_once($CFG->dirroot.'/user/lib.php');
|
||||
@ -657,10 +659,15 @@ class core_enrol_external extends external_api {
|
||||
'search' => $search,
|
||||
'searchanywhere' => $searchanywhere,
|
||||
'page' => $page,
|
||||
'perpage' => $perpage
|
||||
]
|
||||
'perpage' => $perpage,
|
||||
'contextid' => $contextid,
|
||||
],
|
||||
);
|
||||
$context = context_course::instance($params['courseid']);
|
||||
if (isset($contextid)) {
|
||||
$context = context::instance_by_id($params['contextid']);
|
||||
} else {
|
||||
$context = context_course::instance($params['courseid']);
|
||||
}
|
||||
try {
|
||||
self::validate_context($context);
|
||||
} catch (Exception $e) {
|
||||
@ -674,10 +681,14 @@ class core_enrol_external extends external_api {
|
||||
$course = get_course($params['courseid']);
|
||||
$manager = new course_enrolment_manager($PAGE, $course);
|
||||
|
||||
$users = $manager->search_users($params['search'],
|
||||
$params['searchanywhere'],
|
||||
$params['page'],
|
||||
$params['perpage']);
|
||||
$users = $manager->search_users(
|
||||
$params['search'],
|
||||
$params['searchanywhere'],
|
||||
$params['page'],
|
||||
$params['perpage'],
|
||||
false,
|
||||
$params['contextid']
|
||||
);
|
||||
|
||||
$results = [];
|
||||
// Add also extra user fields.
|
||||
|
@ -563,26 +563,40 @@ class course_enrolment_manager {
|
||||
* @param int $page Starting at 0.
|
||||
* @param int $perpage Number of users returned per page.
|
||||
* @param bool $returnexactcount Return the exact total users using count_record or not.
|
||||
* @param ?int $contextid Context ID we are in - we might use search on activity level and its group mode can be different from course group mode.
|
||||
* @return array with two or three elements:
|
||||
* int totalusers Number users matching the search. (This element only exist if $returnexactcount was set to true)
|
||||
* array users List of user objects returned by the query.
|
||||
* boolean moreusers True if there are still more users, otherwise is False.
|
||||
*/
|
||||
public function search_users(string $search = '', bool $searchanywhere = false, int $page = 0, int $perpage = 25,
|
||||
bool $returnexactcount = false) {
|
||||
bool $returnexactcount = false, ?int $contextid = null) {
|
||||
global $USER;
|
||||
|
||||
[$ufields, $joins, $params, $wherecondition] = $this->get_basic_search_conditions($search, $searchanywhere);
|
||||
|
||||
$groupmode = groups_get_course_groupmode($this->course);
|
||||
if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $this->context)) {
|
||||
if (isset($contextid)) {
|
||||
// If contextid is set, we need to determine the group mode that should be used (module or course).
|
||||
[$context, $course, $cm] = get_context_info_array($contextid);
|
||||
// If cm instance is returned, then use the group mode from the module, otherwise get the course group mode.
|
||||
$groupmode = $cm ? groups_get_activity_groupmode($cm, $course) : groups_get_course_groupmode($this->course);
|
||||
} else {
|
||||
// Otherwise, default to the group mode of the course.
|
||||
$context = $this->context;
|
||||
$groupmode = groups_get_course_groupmode($this->course);
|
||||
}
|
||||
|
||||
if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $context)) {
|
||||
$groups = groups_get_all_groups($this->course->id, $USER->id, 0, 'g.id');
|
||||
$groupids = array_column($groups, 'id');
|
||||
if (!$groupids) {
|
||||
return ['totalusers' => 0, 'users' => [], 'moreusers' => false];
|
||||
}
|
||||
} else {
|
||||
$groupids = [];
|
||||
}
|
||||
|
||||
[$enrolledsql, $enrolledparams] = get_enrolled_sql($this->context, '', $groupids);
|
||||
[$enrolledsql, $enrolledparams] = get_enrolled_sql($context, '', $groupids);
|
||||
|
||||
$fields = 'SELECT ' . $ufields;
|
||||
$countfields = 'SELECT COUNT(u.id)';
|
||||
|
@ -18,6 +18,7 @@ namespace core_enrol;
|
||||
|
||||
use context_course;
|
||||
use course_enrolment_manager;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Test course_enrolment_manager parts.
|
||||
@ -557,11 +558,18 @@ class course_enrolment_manager_test extends \advanced_testcase {
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create the forum.
|
||||
$record = new stdClass();
|
||||
$record->introformat = FORMAT_HTML;
|
||||
$record->course = $this->course->id;
|
||||
$forum = self::getDataGenerator()->create_module('forum', $record, ['groupmode' => SEPARATEGROUPS]);
|
||||
$contextid = $DB->get_field('context', 'id', ['instanceid' => $forum->cmid, 'contextlevel' => CONTEXT_MODULE]);
|
||||
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($this->course, 'teacher');
|
||||
$this->getDataGenerator()->create_group_member(['groupid' => $this->groups['group1']->id, 'userid' => $teacher->id]);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$courseusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user0']->username,
|
||||
@ -570,26 +578,49 @@ class course_enrolment_manager_test extends \advanced_testcase {
|
||||
$this->users['user22']->username,
|
||||
$this->users['userall']->username,
|
||||
$this->users['usertch']->username,
|
||||
], array_column($users['users'], 'username'));
|
||||
$this->assertEquals(7, $users['totalusers']);
|
||||
], array_column($courseusers['users'], 'username'));
|
||||
$this->assertEquals(7, $courseusers['totalusers']);
|
||||
|
||||
// Switch course to separate groups.
|
||||
$this->course->groupmode = SEPARATEGROUPS;
|
||||
update_course($this->course);
|
||||
|
||||
$users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$forumusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true, $contextid);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user1']->username,
|
||||
$this->users['userall']->username,
|
||||
], array_column($users['users'], 'username'));
|
||||
$this->assertEquals(3, $users['totalusers']);
|
||||
], array_column($forumusers['users'], 'username'));
|
||||
$this->assertEquals(3, $forumusers['totalusers']);
|
||||
|
||||
// Switch course to separate groups and forum to no group.
|
||||
$this->course->groupmode = SEPARATEGROUPS;
|
||||
update_course($this->course);
|
||||
set_coursemodule_groupmode($forum->cmid, NOGROUPS);
|
||||
|
||||
$courseusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user1']->username,
|
||||
$this->users['userall']->username,
|
||||
], array_column($courseusers['users'], 'username'));
|
||||
$this->assertEquals(3, $courseusers['totalusers']);
|
||||
|
||||
$forumusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true, $contextid);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user0']->username,
|
||||
$this->users['user1']->username,
|
||||
$this->users['user21']->username,
|
||||
$this->users['user22']->username,
|
||||
$this->users['userall']->username,
|
||||
$this->users['usertch']->username,
|
||||
], array_column($forumusers['users'], 'username'));
|
||||
$this->assertEquals(7, $forumusers['totalusers']);
|
||||
|
||||
set_coursemodule_groupmode($forum->cmid, SEPARATEGROUPS);
|
||||
|
||||
// Allow teacher to access all groups.
|
||||
$roleid = $DB->get_field('role', 'id', ['shortname' => 'teacher']);
|
||||
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, context_course::instance($this->course->id)->id);
|
||||
|
||||
$users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$courseusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user0']->username,
|
||||
@ -598,7 +629,19 @@ class course_enrolment_manager_test extends \advanced_testcase {
|
||||
$this->users['user22']->username,
|
||||
$this->users['userall']->username,
|
||||
$this->users['usertch']->username,
|
||||
], array_column($users['users'], 'username'));
|
||||
$this->assertEquals(7, $users['totalusers']);
|
||||
], array_column($courseusers['users'], 'username'));
|
||||
$this->assertEquals(7, $courseusers['totalusers']);
|
||||
|
||||
$forumusers = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true, $contextid);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$teacher->username,
|
||||
$this->users['user0']->username,
|
||||
$this->users['user1']->username,
|
||||
$this->users['user21']->username,
|
||||
$this->users['user22']->username,
|
||||
$this->users['userall']->username,
|
||||
$this->users['usertch']->username,
|
||||
], array_column($forumusers['users'], 'username'));
|
||||
$this->assertEquals(7, $forumusers['totalusers']);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use core_enrol_external;
|
||||
use core_external\external_api;
|
||||
use enrol_user_enrolment_form;
|
||||
use externallib_advanced_testcase;
|
||||
use stdClass;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -1421,6 +1422,71 @@ class externallib_test extends externallib_advanced_testcase {
|
||||
$this->assertCount(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for core_enrol_external::search_users() when group mode is active.
|
||||
* @covers ::search_users
|
||||
*/
|
||||
public function test_search_users_groupmode() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$datagen = $this->getDataGenerator();
|
||||
|
||||
$studentroleid = $DB->get_field('role', 'id', ['shortname' => 'student'], MUST_EXIST);
|
||||
$teacherroleid = $DB->get_field('role', 'id', ['shortname' => 'teacher'], MUST_EXIST);
|
||||
|
||||
$course = $datagen->create_course();
|
||||
|
||||
$student1 = $datagen->create_and_enrol($course);
|
||||
$student2 = $datagen->create_and_enrol($course);
|
||||
$student3 = $datagen->create_and_enrol($course);
|
||||
$teacher1 = $datagen->create_and_enrol($course, 'teacher');
|
||||
$teacher2 = $datagen->create_and_enrol($course, 'teacher');
|
||||
$teacher3 = $datagen->create_and_enrol($course, 'teacher');
|
||||
$teacher4 = $datagen->create_and_enrol($course, 'editingteacher');
|
||||
|
||||
// Create 2 groups.
|
||||
$group1 = $datagen->create_group(['courseid' => $course->id]);
|
||||
$group2 = $datagen->create_group(['courseid' => $course->id]);
|
||||
|
||||
// Add the users to the groups.
|
||||
$datagen->create_group_member(['groupid' => $group1->id, 'userid' => $student1->id]);
|
||||
$datagen->create_group_member(['groupid' => $group2->id, 'userid' => $student2->id]);
|
||||
$datagen->create_group_member(['groupid' => $group2->id, 'userid' => $student3->id]);
|
||||
$datagen->create_group_member(['groupid' => $group1->id, 'userid' => $teacher1->id]);
|
||||
$datagen->create_group_member(['groupid' => $group2->id, 'userid' => $teacher1->id]);
|
||||
$datagen->create_group_member(['groupid' => $group1->id, 'userid' => $teacher2->id]);
|
||||
|
||||
// Create the forum.
|
||||
$record = new stdClass();
|
||||
$record->introformat = FORMAT_HTML;
|
||||
$record->course = $course->id;
|
||||
$forum = self::getDataGenerator()->create_module('forum', $record, ['groupmode' => SEPARATEGROUPS]);
|
||||
$contextid = $DB->get_field('context', 'id', ['instanceid' => $forum->cmid, 'contextlevel' => CONTEXT_MODULE]);
|
||||
|
||||
$this->setUser($teacher1);
|
||||
$result = core_enrol_external::search_users($course->id, 'user', true, 0, 30, $contextid);
|
||||
$this->assertCount(5, $result);
|
||||
|
||||
$this->setUser($teacher2);
|
||||
$result = core_enrol_external::search_users($course->id, 'user', true, 0, 30, $contextid);
|
||||
$this->assertCount(3, $result);
|
||||
|
||||
$this->setUser($teacher3);
|
||||
$result = core_enrol_external::search_users($course->id, 'user', true, 0, 30, $contextid);
|
||||
$this->assertCount(0, $result);
|
||||
|
||||
$this->setUser($teacher4);
|
||||
$result = core_enrol_external::search_users($course->id, 'user', true, 0, 30, $contextid);
|
||||
$this->assertCount(7, $result);
|
||||
|
||||
// Now change the group mode to no groups.
|
||||
set_coursemodule_groupmode($forum->cmid, NOGROUPS);
|
||||
$this->setUser($teacher1);
|
||||
$result = core_enrol_external::search_users($course->id, 'user', true, 0, 30, $contextid);
|
||||
$this->assertCount(7, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the get_potential_users external function (not too much detail because the back-end
|
||||
* is covered in another test).
|
||||
|
@ -3,6 +3,8 @@ information provided here is intended especially for developers.
|
||||
|
||||
=== 4.4 ===
|
||||
|
||||
* Functions core_enrol_external::search_users and course_enrolment_manager::search_users now have extra optional parameter
|
||||
contextid which allows to search users in a specific activity context. When omitted it searches in the whole course.
|
||||
* New find_instance() function has been created. It finds a matching enrolment instance in a given course using provided
|
||||
enrolment data (for example cohort idnumber for cohort enrolment). Defaults to null. Override this function in your
|
||||
enrolment plugin if you want it to be supported in CSV course upload. Please be aware that sometimes it is not possible
|
||||
|
@ -5,6 +5,6 @@
|
||||
* @copyright 2019 Shamim Rezaie
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define("mod_forum/form-user-selector",["jquery","core/ajax","core/templates"],(function($,Ajax,Templates){return{processResults:function(selector,results){var users=[];return $.each(results,(function(index,user){users.push({value:user.id,label:user._label})})),users},transport:function(selector,query,success,failure){var courseid=$(selector).attr("courseid");Ajax.call([{methodname:"core_enrol_search_users",args:{courseid:courseid,search:query,searchanywhere:!0,page:0,perpage:30}}])[0].then((function(results){var promises=[],i=0;return $.each(results,(function(index,user){promises.push(Templates.render("mod_forum/form-user-selector-suggestion",user))})),$.when.apply($.when,promises).then((function(){var args=arguments;$.each(results,(function(index,user){user._label=args[i],i++})),success(results)}))})).fail(failure)}}}));
|
||||
define("mod_forum/form-user-selector",["jquery","core/ajax","core/templates"],(function($,Ajax,Templates){return{processResults:function(selector,results){var users=[];return $.each(results,(function(index,user){users.push({value:user.id,label:user._label})})),users},transport:function(selector,query,success,failure){var courseid=$(selector).attr("courseid"),contextid=$(selector).attr("data-contextid");Ajax.call([{methodname:"core_enrol_search_users",args:{courseid:courseid,search:query,searchanywhere:!0,page:0,perpage:30,contextid:contextid}}])[0].then((function(results){var promises=[],i=0;return $.each(results,(function(index,user){promises.push(Templates.render("mod_forum/form-user-selector-suggestion",user))})),$.when.apply($.when,promises).then((function(){var args=arguments;$.each(results,(function(index,user){user._label=args[i],i++})),success(results)}))})).fail(failure)}}}));
|
||||
|
||||
//# sourceMappingURL=form-user-selector.min.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"form-user-selector.min.js","sources":["../src/form-user-selector.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Enrolled user selector module.\n *\n * @module mod_forum/form-user-selector\n * @copyright 2019 Shamim Rezaie\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {\n return /** @alias module:mod_forum/form-user-selector */ {\n processResults: function(selector, results) {\n var users = [];\n $.each(results, function(index, user) {\n users.push({\n value: user.id,\n label: user._label\n });\n });\n return users;\n },\n\n transport: function(selector, query, success, failure) {\n var promise;\n var courseid = $(selector).attr('courseid');\n\n promise = Ajax.call([{\n methodname: 'core_enrol_search_users',\n args: {\n courseid: courseid,\n search: query,\n searchanywhere: true,\n page: 0,\n perpage: 30\n }\n }]);\n\n promise[0].then(function(results) {\n var promises = [],\n i = 0;\n\n // Render the label.\n $.each(results, function(index, user) {\n promises.push(Templates.render('mod_forum/form-user-selector-suggestion', user));\n });\n\n // Apply the label to the results.\n return $.when.apply($.when, promises).then(function() {\n var args = arguments;\n $.each(results, function(index, user) {\n user._label = args[i];\n i++;\n });\n success(results);\n return;\n });\n\n }).fail(failure);\n }\n\n };\n\n});\n"],"names":["define","$","Ajax","Templates","processResults","selector","results","users","each","index","user","push","value","id","label","_label","transport","query","success","failure","courseid","attr","call","methodname","args","search","searchanywhere","page","perpage","then","promises","i","render","when","apply","arguments","fail"],"mappings":";;;;;;;AAuBAA,sCAAO,CAAC,SAAU,YAAa,mBAAmB,SAASC,EAAGC,KAAMC,iBACP,CACrDC,eAAgB,SAASC,SAAUC,aAC3BC,MAAQ,UACZN,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BH,MAAMI,KAAK,CACPC,MAAOF,KAAKG,GACZC,MAAOJ,KAAKK,YAGbR,OAGXS,UAAW,SAASX,SAAUY,MAAOC,QAASC,aAEtCC,SAAWnB,EAAEI,UAAUgB,KAAK,YAEtBnB,KAAKoB,KAAK,CAAC,CACjBC,WAAY,0BACZC,KAAM,CACFJ,SAAUA,SACVK,OAAQR,MACRS,gBAAgB,EAChBC,KAAM,EACNC,QAAS,OAIT,GAAGC,MAAK,SAASvB,aACjBwB,SAAW,GACXC,EAAI,SAGR9B,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BoB,SAASnB,KAAKR,UAAU6B,OAAO,0CAA2CtB,UAIvET,EAAEgC,KAAKC,MAAMjC,EAAEgC,KAAMH,UAAUD,MAAK,eACnCL,KAAOW,UACXlC,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BA,KAAKK,OAASS,KAAKO,GACnBA,OAEJb,QAAQZ,eAIb8B,KAAKjB"}
|
||||
{"version":3,"file":"form-user-selector.min.js","sources":["../src/form-user-selector.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Enrolled user selector module.\n *\n * @module mod_forum/form-user-selector\n * @copyright 2019 Shamim Rezaie\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {\n return /** @alias module:mod_forum/form-user-selector */ {\n processResults: function(selector, results) {\n var users = [];\n $.each(results, function(index, user) {\n users.push({\n value: user.id,\n label: user._label\n });\n });\n return users;\n },\n\n transport: function(selector, query, success, failure) {\n var promise;\n var courseid = $(selector).attr('courseid');\n var contextid = $(selector).attr('data-contextid');\n\n promise = Ajax.call([{\n methodname: 'core_enrol_search_users',\n args: {\n courseid: courseid,\n search: query,\n searchanywhere: true,\n page: 0,\n perpage: 30,\n contextid: contextid,\n }\n }]);\n\n promise[0].then(function(results) {\n var promises = [],\n i = 0;\n\n // Render the label.\n $.each(results, function(index, user) {\n promises.push(Templates.render('mod_forum/form-user-selector-suggestion', user));\n });\n\n // Apply the label to the results.\n return $.when.apply($.when, promises).then(function() {\n var args = arguments;\n $.each(results, function(index, user) {\n user._label = args[i];\n i++;\n });\n success(results);\n return;\n });\n\n }).fail(failure);\n }\n\n };\n\n});\n"],"names":["define","$","Ajax","Templates","processResults","selector","results","users","each","index","user","push","value","id","label","_label","transport","query","success","failure","courseid","attr","contextid","call","methodname","args","search","searchanywhere","page","perpage","then","promises","i","render","when","apply","arguments","fail"],"mappings":";;;;;;;AAuBAA,sCAAO,CAAC,SAAU,YAAa,mBAAmB,SAASC,EAAGC,KAAMC,iBACP,CACrDC,eAAgB,SAASC,SAAUC,aAC3BC,MAAQ,UACZN,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BH,MAAMI,KAAK,CACPC,MAAOF,KAAKG,GACZC,MAAOJ,KAAKK,YAGbR,OAGXS,UAAW,SAASX,SAAUY,MAAOC,QAASC,aAEtCC,SAAWnB,EAAEI,UAAUgB,KAAK,YAC5BC,UAAYrB,EAAEI,UAAUgB,KAAK,kBAEvBnB,KAAKqB,KAAK,CAAC,CACjBC,WAAY,0BACZC,KAAM,CACFL,SAAUA,SACVM,OAAQT,MACRU,gBAAgB,EAChBC,KAAM,EACNC,QAAS,GACTP,UAAWA,cAIX,GAAGQ,MAAK,SAASxB,aACjByB,SAAW,GACXC,EAAI,SAGR/B,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BqB,SAASpB,KAAKR,UAAU8B,OAAO,0CAA2CvB,UAIvET,EAAEiC,KAAKC,MAAMlC,EAAEiC,KAAMH,UAAUD,MAAK,eACnCL,KAAOW,UACXnC,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BA,KAAKK,OAASU,KAAKO,GACnBA,OAEJd,QAAQZ,eAIb+B,KAAKlB"}
|
@ -37,6 +37,7 @@ define(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {
|
||||
transport: function(selector, query, success, failure) {
|
||||
var promise;
|
||||
var courseid = $(selector).attr('courseid');
|
||||
var contextid = $(selector).attr('data-contextid');
|
||||
|
||||
promise = Ajax.call([{
|
||||
methodname: 'core_enrol_search_users',
|
||||
@ -45,7 +46,8 @@ define(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {
|
||||
search: query,
|
||||
searchanywhere: true,
|
||||
page: 0,
|
||||
perpage: 30
|
||||
perpage: 30,
|
||||
contextid: contextid,
|
||||
}
|
||||
}]);
|
||||
|
||||
|
@ -53,6 +53,7 @@ class export_form extends \moodleform {
|
||||
'ajax' => 'mod_forum/form-user-selector',
|
||||
'multiple' => true,
|
||||
'noselectionstring' => get_string('allusers', 'mod_forum'),
|
||||
'data-contextid' => $forum->get_context()->id,
|
||||
'courseid' => $forum->get_course_id(),
|
||||
'valuehtmlcallback' => function($value) {
|
||||
global $OUTPUT;
|
||||
@ -69,7 +70,6 @@ class export_form extends \moodleform {
|
||||
];
|
||||
$mform->addElement('autocomplete', 'useridsselected', get_string('users'), [], $options);
|
||||
|
||||
// Get the discussions on this forum.
|
||||
$vaultfactory = \mod_forum\local\container::get_vault_factory();
|
||||
$discussionvault = $vaultfactory->get_discussion_vault();
|
||||
$discussions = array_map(function($discussion) {
|
||||
|
@ -26,6 +26,7 @@ namespace mod_forum\local\vaults;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use mod_forum\local\container;
|
||||
use mod_forum\local\entities\forum as forum_entity;
|
||||
use mod_forum\local\entities\discussion as discussion_entity;
|
||||
|
||||
@ -93,9 +94,23 @@ class discussion extends db_table_vault {
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_discussions_in_forum(forum_entity $forum, string $sort = null): ?array {
|
||||
$records = $this->get_db()->get_records(self::TABLE, [
|
||||
'forum' => $forum->get_id(),
|
||||
], $sort ?? '');
|
||||
global $USER;
|
||||
$options = ['forum' => $forum->get_id()];
|
||||
|
||||
$managerfactory = container::get_manager_factory();
|
||||
$capabilitymanager = $managerfactory->get_capability_manager($forum);
|
||||
|
||||
$select = "forum = :forum";
|
||||
|
||||
if ($forum->is_in_group_mode() && !$capabilitymanager->can_access_all_groups($USER)) {
|
||||
$allowedgroups = groups_get_activity_allowed_groups($forum->get_course_module_record());
|
||||
$allowedgroups = implode(",", array_keys($allowedgroups));
|
||||
if (!$allowedgroups) {
|
||||
return [];
|
||||
}
|
||||
$select .= " AND groupid IN ($allowedgroups)";
|
||||
}
|
||||
$records = $this->get_db()->get_records_select(self::TABLE, $select, $options, $sort ?? '');
|
||||
|
||||
return $this->transform_db_records_to_entities($records);
|
||||
}
|
||||
|
@ -192,8 +192,7 @@ if (!$PAGE->has_secondary_navigation()) {
|
||||
|
||||
// It is possible that the following fields have been provided in the URL.
|
||||
$userids = array_filter($userids, static function(int $userid) use ($course, $cm): bool {
|
||||
$user = core_user::get_user($userid, '*', MUST_EXIST);
|
||||
return $cm->effectivegroupmode != SEPARATEGROUPS || user_can_view_profile($user, $course);
|
||||
return $cm->effectivegroupmode != SEPARATEGROUPS || groups_user_groups_visible($course, $userid, $cm);
|
||||
});
|
||||
$form->set_data(['useridsselected' => $userids, 'discussionids' => $discussionids, 'from' => $from, 'to' => $to]);
|
||||
|
||||
|
@ -48,3 +48,125 @@ Feature: Export forum
|
||||
# This will fail if an exception is thrown. This is the best we can do without the ability to use the download. Hence, there is no "Then" step.
|
||||
And I click on "Export" "button"
|
||||
And I log out
|
||||
|
||||
Scenario: Group mode is respected when exporting discussions
|
||||
Given the following "groups" exist:
|
||||
| name | course | idnumber |
|
||||
| G1 | C1 | G1 |
|
||||
| G2 | C1 | G2 |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teachera | Teacher | A | teacherA@example.com |
|
||||
| teacherb | Teacher | B | teacherB@example.com |
|
||||
| teacherc | Teacher | C | teacherC@example.com |
|
||||
| teacherd | Teacher | D | teacherD@example.com |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teachera | C1 | teacher |
|
||||
| teacherb | C1 | teacher |
|
||||
| teacherc | C1 | teacher |
|
||||
| teacherd | C1 | teacher |
|
||||
And the following "group members" exist:
|
||||
| user | group |
|
||||
| teachera | G1 |
|
||||
| teachera | G2 |
|
||||
| teacherb | G1 |
|
||||
| teacherc | G2 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | type | section | groupmode |
|
||||
| forum | C1 | 00001 | Separate groups forum | Standard forum description | general | 1 | 1 |
|
||||
And the following "mod_forum > discussions" exist:
|
||||
| user | forum | name | message | group |
|
||||
| teachera | Separate groups forum | Discussion 1 Group 1 | Test post message | G1 |
|
||||
| teacherb | Separate groups forum | Discussion 2 Group 1 | Test post message | G1 |
|
||||
| teachera | Separate groups forum | Discussion 1 Group 2 | Test post message | G2 |
|
||||
| teacherc | Separate groups forum | Discussion 2 Group 2 | Test post message | G2 |
|
||||
And I am on the "Separate groups forum" "forum activity" page logged in as teacher1
|
||||
And I navigate to "Export" in current page administration
|
||||
When I expand the "Users" autocomplete
|
||||
# Editing teacher can see all users and discussions.
|
||||
Then I should see "Teacher A" in the "Users" "autocomplete"
|
||||
And I should see "Teacher B" in the "Users" "autocomplete"
|
||||
And I should see "Teacher C" in the "Users" "autocomplete"
|
||||
And I should see "Teacher D" in the "Users" "autocomplete"
|
||||
And I should see "Teacher 1" in the "Users" "autocomplete"
|
||||
And I should see "Student 1" in the "Users" "autocomplete"
|
||||
And I press the escape key
|
||||
And I expand the "Discussions" autocomplete
|
||||
And I should see "Discussion 1 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 1 Group 2" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 2" in the "Discussions" "autocomplete"
|
||||
And I click on "Export" "button"
|
||||
|
||||
And I am on the "Separate groups forum" "forum activity" page logged in as teachera
|
||||
And I navigate to "Export" in current page administration
|
||||
When I expand the "Users" autocomplete
|
||||
# Teacher A is is in both groups.
|
||||
Then I should see "Teacher A" in the "Users" "autocomplete"
|
||||
And I should see "Teacher B" in the "Users" "autocomplete"
|
||||
And I should see "Teacher C" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher D" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher 1" in the "Users" "autocomplete"
|
||||
And I should not see "Student 1" in the "Users" "autocomplete"
|
||||
And I press the escape key
|
||||
And I expand the "Discussions" autocomplete
|
||||
And I should see "Discussion 1 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 1 Group 2" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 2" in the "Discussions" "autocomplete"
|
||||
And I click on "Export" "button"
|
||||
|
||||
And I am on the "Separate groups forum" "forum activity" page logged in as teacherb
|
||||
And I navigate to "Export" in current page administration
|
||||
When I expand the "Users" autocomplete
|
||||
# Teacher B is in group 1.
|
||||
Then I should see "Teacher A" in the "Users" "autocomplete"
|
||||
And I should see "Teacher B" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher C" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher D" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher 1" in the "Users" "autocomplete"
|
||||
And I should not see "Student 1" in the "Users" "autocomplete"
|
||||
And I press the escape key
|
||||
And I expand the "Discussions" autocomplete
|
||||
And I should see "Discussion 1 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 1 Group 2" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 2 Group 2" in the "Discussions" "autocomplete"
|
||||
And I click on "Export" "button"
|
||||
|
||||
And I am on the "Separate groups forum" "forum activity" page logged in as teacherc
|
||||
And I navigate to "Export" in current page administration
|
||||
When I expand the "Users" autocomplete
|
||||
# Teacher C is in group 2.
|
||||
Then I should see "Teacher A" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher B" in the "Users" "autocomplete"
|
||||
And I should see "Teacher C" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher D" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher 1" in the "Users" "autocomplete"
|
||||
And I should not see "Student 1" in the "Users" "autocomplete"
|
||||
And I press the escape key
|
||||
And I expand the "Discussions" autocomplete
|
||||
And I should not see "Discussion 1 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 2 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 1 Group 2" in the "Discussions" "autocomplete"
|
||||
And I should see "Discussion 2 Group 2" in the "Discussions" "autocomplete"
|
||||
And I click on "Export" "button"
|
||||
|
||||
And I am on the "Separate groups forum" "forum activity" page logged in as teacherd
|
||||
And I navigate to "Export" in current page administration
|
||||
When I expand the "Users" autocomplete
|
||||
# Teacher D is in no group.
|
||||
Then I should not see "Teacher A" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher B" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher C" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher D" in the "Users" "autocomplete"
|
||||
And I should not see "Teacher 1" in the "Users" "autocomplete"
|
||||
And I should not see "Student 1" in the "Users" "autocomplete"
|
||||
And I press the escape key
|
||||
And I expand the "Discussions" autocomplete
|
||||
And I should not see "Discussion 1 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 2 Group 1" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 1 Group 2" in the "Discussions" "autocomplete"
|
||||
And I should not see "Discussion 2 Group 2" in the "Discussions" "autocomplete"
|
||||
And I click on "Export" "button"
|
||||
|
Loading…
x
Reference in New Issue
Block a user