MDL-68437 forum: Support to show only active course users in grader
The following change adds support to show only active course users in the forum grader and generally replicates the behaviour from the assignment grader which relies on certain config settings, user permissions and capabilities.
This commit is contained in:
+1
-1
@@ -5,6 +5,6 @@ define("mod_forum/grades/grader",["exports","./grader/selectors","mod_forum/repo
|
||||
* @module mod_forum/grades/grader
|
||||
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.registerLaunchListeners=void 0,Selectors=_interopRequireWildcard(Selectors),_repository=_interopRequireDefault(_repository),_templates=_interopRequireDefault(_templates),Grader=_interopRequireWildcard(Grader),_notification=_interopRequireDefault(_notification),_repository2=_interopRequireDefault(_repository2);const templateNames_contentRegion="mod_forum/grades/grader/discussion/posts",getContentForUserIdFunction=(cmid,experimentalDisplayMode)=>userid=>_repository.default.getDiscussionByUserID(userid,cmid).then((context=>(context.discussions=context.discussions.map(discussionPostMapper),context.experimentaldisplaymode=!!experimentalDisplayMode,_templates.default.render(templateNames_contentRegion,context)))).catch(_notification.default.exception),getUsersForCmidFunction=(cmid,groupID)=>async()=>(await _repository2.default.getUsersFromCourseModuleID(cmid,groupID)).users,findGradableNode=node=>node.closest(Selectors.gradableItem),discussionPostMapper=discussion=>{const parentMap=new Map;discussion.posts.parentposts.forEach((post=>parentMap.set(post.id,post)));const userPosts=discussion.posts.userposts.map((post=>{post.readonly=!0,post.hasreplies=!1,post.replies=[];const parent=post.parentid?parentMap.get(post.parentid):null;return parent&&(parent.hasreplies=!1,parent.replies=[],parent.readonly=!0,post.parentauthorname=parent.author.fullname),{parent:parent,post:post}}));return{...discussion,posts:userPosts}};_exports.registerLaunchListeners=()=>{document.addEventListener("click",(async e=>{if(e.target.matches(Selectors.launch)){const rootNode=findGradableNode(e.target);if(!rootNode)throw Error("Unable to find a gradable item");if(!rootNode.matches(Selectors.gradableItems.wholeForum))throw Error("Unable to find a valid gradable item");e.preventDefault();try{await async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const data=rootNode.dataset,gradingPanelFunctions=await Grader.getGradingPanelFunctions("mod_forum",data.contextid,data.gradingComponent,data.gradingComponentSubtype,data.gradableItemtype),groupID=data.group?data.group:0;await Grader.launch(getUsersForCmidFunction(data.cmid,groupID),getContentForUserIdFunction(data.cmid,"1"==data.experimentalDisplayMode),gradingPanelFunctions.getter,gradingPanelFunctions.setter,{groupid:data.groupid,initialUserId:data.initialuserid,moduleName:data.name,courseName:data.courseName,courseUrl:(0,_url.relativeUrl)("/course/view.php",{id:data.courseId}),sendStudentNotifications:data.sendStudentNotifications,focusOnClose:focusOnClose})}(rootNode,{focusOnClose:e.target})}catch(error){_notification.default.exception(error)}}if(e.target.matches(Selectors.viewGrade)){e.preventDefault();const rootNode=findGradableNode(e.target);if(!rootNode)throw Error("Unable to find a gradable item");if(!rootNode.matches(Selectors.gradableItems.wholeForum))throw Error("Unable to find a valid gradable item");e.preventDefault();try{await async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const data=rootNode.dataset,gradingPanelFunctions=await Grader.getGradingPanelFunctions("mod_forum",data.contextid,data.gradingComponent,data.gradingComponentSubtype,data.gradableItemtype);await Grader.view(gradingPanelFunctions.getter,data.userid,data.name,{focusOnClose:focusOnClose})}(rootNode,{focusOnClose:e.target})}catch(error){_notification.default.exception(error)}}}))}}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.registerLaunchListeners=void 0,Selectors=_interopRequireWildcard(Selectors),_repository=_interopRequireDefault(_repository),_templates=_interopRequireDefault(_templates),Grader=_interopRequireWildcard(Grader),_notification=_interopRequireDefault(_notification),_repository2=_interopRequireDefault(_repository2);const templateNames_contentRegion="mod_forum/grades/grader/discussion/posts",getContentForUserIdFunction=(cmid,experimentalDisplayMode)=>userid=>_repository.default.getDiscussionByUserID(userid,cmid).then((context=>(context.discussions=context.discussions.map(discussionPostMapper),context.experimentaldisplaymode=!!experimentalDisplayMode,_templates.default.render(templateNames_contentRegion,context)))).catch(_notification.default.exception),getUsersForCmidFunction=(cmid,groupID,onlyActive)=>async()=>(await _repository2.default.getUsersFromCourseModuleID(cmid,groupID,onlyActive)).users,findGradableNode=node=>node.closest(Selectors.gradableItem),discussionPostMapper=discussion=>{const parentMap=new Map;discussion.posts.parentposts.forEach((post=>parentMap.set(post.id,post)));const userPosts=discussion.posts.userposts.map((post=>{post.readonly=!0,post.hasreplies=!1,post.replies=[];const parent=post.parentid?parentMap.get(post.parentid):null;return parent&&(parent.hasreplies=!1,parent.replies=[],parent.readonly=!0,post.parentauthorname=parent.author.fullname),{parent:parent,post:post}}));return{...discussion,posts:userPosts}};_exports.registerLaunchListeners=()=>{document.addEventListener("click",(async e=>{if(e.target.matches(Selectors.launch)){const rootNode=findGradableNode(e.target);if(!rootNode)throw Error("Unable to find a gradable item");if(!rootNode.matches(Selectors.gradableItems.wholeForum))throw Error("Unable to find a valid gradable item");e.preventDefault();try{await async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const data=rootNode.dataset,gradingPanelFunctions=await Grader.getGradingPanelFunctions("mod_forum",data.contextid,data.gradingComponent,data.gradingComponentSubtype,data.gradableItemtype),groupID=data.group?data.group:0,onlyActive=data.gradeOnlyActiveUsers;await Grader.launch(getUsersForCmidFunction(data.cmid,groupID,onlyActive),getContentForUserIdFunction(data.cmid,"1"==data.experimentalDisplayMode),gradingPanelFunctions.getter,gradingPanelFunctions.setter,{groupid:data.groupid,initialUserId:data.initialuserid,moduleName:data.name,courseName:data.courseName,courseUrl:(0,_url.relativeUrl)("/course/view.php",{id:data.courseId}),sendStudentNotifications:data.sendStudentNotifications,focusOnClose:focusOnClose})}(rootNode,{focusOnClose:e.target})}catch(error){_notification.default.exception(error)}}if(e.target.matches(Selectors.viewGrade)){e.preventDefault();const rootNode=findGradableNode(e.target);if(!rootNode)throw Error("Unable to find a gradable item");if(!rootNode.matches(Selectors.gradableItems.wholeForum))throw Error("Unable to find a valid gradable item");e.preventDefault();try{await async function(rootNode){let{focusOnClose:focusOnClose=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const data=rootNode.dataset,gradingPanelFunctions=await Grader.getGradingPanelFunctions("mod_forum",data.contextid,data.gradingComponent,data.gradingComponentSubtype,data.gradableItemtype);await Grader.view(gradingPanelFunctions.getter,data.userid,data.name,{focusOnClose:focusOnClose})}(rootNode,{focusOnClose:e.target})}catch(error){_notification.default.exception(error)}}}))}}));
|
||||
|
||||
//# sourceMappingURL=grader.min.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -62,10 +62,11 @@ const getContentForUserIdFunction = (cmid, experimentalDisplayMode) => (userid)
|
||||
*
|
||||
* @param {Number} cmid
|
||||
* @param {Number} groupID
|
||||
* @param {Boolean} onlyActive Whether to fetch only the active enrolled users or all enrolled users in the course.
|
||||
* @return {Array} Array of users for a given context.
|
||||
*/
|
||||
const getUsersForCmidFunction = (cmid, groupID) => async() => {
|
||||
const context = await CourseRepository.getUsersFromCourseModuleID(cmid, groupID);
|
||||
const getUsersForCmidFunction = (cmid, groupID, onlyActive) => async() => {
|
||||
const context = await CourseRepository.getUsersFromCourseModuleID(cmid, groupID, onlyActive);
|
||||
|
||||
return context.users;
|
||||
};
|
||||
@@ -128,9 +129,10 @@ const launchWholeForumGrading = async(rootNode, {
|
||||
);
|
||||
|
||||
const groupID = data.group ? data.group : 0;
|
||||
const onlyActive = data.gradeOnlyActiveUsers;
|
||||
|
||||
await Grader.launch(
|
||||
getUsersForCmidFunction(data.cmid, groupID),
|
||||
getUsersForCmidFunction(data.cmid, groupID, onlyActive),
|
||||
getContentForUserIdFunction(data.cmid, data.experimentalDisplayMode == "1"),
|
||||
gradingPanelFunctions.getter,
|
||||
gradingPanelFunctions.setter,
|
||||
|
||||
@@ -236,6 +236,23 @@ class forum_gradeitem extends component_gradeitem {
|
||||
return (int) $this->forum->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether only active users in the course should be gradeable.
|
||||
*
|
||||
* @return bool Whether only active users in the course should be gradeable.
|
||||
*/
|
||||
public function should_grade_only_active_users(): bool {
|
||||
global $CFG;
|
||||
|
||||
$showonlyactiveenrolconfig = !empty($CFG->grade_report_showonlyactiveenrol);
|
||||
// Grade only active users enrolled in the course either when the 'grade_report_showonlyactiveenrol' user
|
||||
// preference is set to true or the current user does not have the capability to view suspended users in the
|
||||
// course. In cases where the 'grade_report_showonlyactiveenrol' user preference is not set we are falling back
|
||||
// to the set value for the 'grade_report_showonlyactiveenrol' config.
|
||||
return get_user_preferences('grade_report_showonlyactiveenrol', $showonlyactiveenrolconfig) ||
|
||||
!has_capability('moodle/course:viewsuspendedusers', \context_course::instance($this->forum->get_course_id()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update the grade.
|
||||
*
|
||||
|
||||
@@ -197,6 +197,7 @@ class discussion_list {
|
||||
'gradingcomponent' => $this->forumgradeitem->get_grading_component_name(),
|
||||
'gradingcomponentsubtype' => $this->forumgradeitem->get_grading_component_subtype(),
|
||||
'sendstudentnotifications' => $forum->should_notify_students_default_when_grade_for_forum(),
|
||||
'gradeonlyactiveusers' => $this->forumgradeitem->should_grade_only_active_users(),
|
||||
'hasanyactions' => $hasanyactions,
|
||||
'groupchangemenu' => groups_print_activity_menu(
|
||||
$cm,
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
data-grading-component="{{gradingcomponent}}"
|
||||
data-grading-component-subtype="{{gradingcomponentsubtype}}"
|
||||
data-gradable-itemtype="forum"
|
||||
data-grade-only-active-users="{{gradeonlyactiveusers}}"
|
||||
{{#sendstudentnotifications}}data-send-student-notifications="1" {{/sendstudentnotifications}}
|
||||
>
|
||||
{{#str}}gradeusers, forum{{/str}}
|
||||
|
||||
@@ -169,6 +169,91 @@ class grades_forum_gradeitem_test extends \advanced_testcase {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the logic in the should_grade_only_active_users() method.
|
||||
*
|
||||
* @covers ::should_grade_only_active_users
|
||||
* @dataProvider should_grade_only_active_users_provider
|
||||
* @param bool $showonlyactiveenrolconfig Whether the 'grade_report_showonlyactiveenrol' is enabled or not.
|
||||
* @param bool $showonlyactiveenrolpreference Whether the 'grade_report_showonlyactiveenrol' preference is enabled or not.
|
||||
* @param bool $viewsuspendeduserscapability Whether the 'moodle/course:viewsuspendedusers' capability is allowed or not.
|
||||
* @param bool $expected The expected result.
|
||||
*/
|
||||
public function test_should_grade_only_active_users(bool $showonlyactiveenrolconfig, bool $showonlyactiveenrolpreference,
|
||||
bool $viewsuspendeduserscapability, bool $expected): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$forum = $this->get_forum_instance([
|
||||
'grade_forum' => 100,
|
||||
]);
|
||||
$course = $forum->get_course_record();
|
||||
$gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum');
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher');
|
||||
$editingteacherroleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
|
||||
|
||||
// Set the 'grade_report_showonlyactiveenrol' config setting.
|
||||
set_config('grade_report_showonlyactiveenrol', $showonlyactiveenrolconfig);
|
||||
|
||||
$this->setUser($user);
|
||||
// Set the 'grade_report_showonlyactiveenrol' user preference.
|
||||
set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrolpreference);
|
||||
|
||||
// Set the 'moodle/course:viewsuspendedusers' user capability.
|
||||
assign_capability('moodle/course:viewsuspendedusers', $viewsuspendeduserscapability ?
|
||||
CAP_ALLOW : CAP_PROHIBIT, $editingteacherroleid, \context_course::instance($course->id));
|
||||
|
||||
$this->assertEquals($expected, $gradeitem->should_grade_only_active_users());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_should_grade_only_active_users.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function should_grade_only_active_users_provider(): array {
|
||||
return [
|
||||
'Enabled showonlyactiveenrol setting; enabled showonlyactiveenrol preference; view suspended users capability' =>
|
||||
[
|
||||
'showonlyactiveenrolconfig' => true,
|
||||
'showonlyactiveenrolpreference' => true,
|
||||
'viewsuspendeduserscapability' => true,
|
||||
'expected' => true,
|
||||
],
|
||||
'Disabled showonlyactiveenrol setting; enabled showonlyactiveenrol preference; view suspended users capability' =>
|
||||
[
|
||||
'showonlyactiveenrolconfig' => false,
|
||||
'showonlyactiveenrolpreference' => true,
|
||||
'viewsuspendeduserscapability' => true,
|
||||
'expected' => true,
|
||||
],
|
||||
'Disabled showonlyactiveenrol setting; disabled showonlyactiveenrol preference; view suspended users capability' =>
|
||||
[
|
||||
'showonlyactiveenrolconfig' => false,
|
||||
'showonlyactiveenrolpreference' => false,
|
||||
'viewsuspendeduserscapability' => true,
|
||||
'expected' => false,
|
||||
],
|
||||
'Disabled showonlyactiveenrol setting; disabled showonlyactiveenrol preference; no view suspended users capability' =>
|
||||
[
|
||||
'showonlyactiveenrolconfig' => false,
|
||||
'showonlyactiveenrolpreference' => false,
|
||||
'viewsuspendeduserscapability' => false,
|
||||
'expected' => true,
|
||||
],
|
||||
'Enabled showonlyactiveenrol setting; enabled showonlyactiveenrol preference; no view suspended users capability' =>
|
||||
[
|
||||
'showonlyactiveenrolconfig' => true,
|
||||
'showonlyactiveenrolpreference' => true,
|
||||
'viewsuspendeduserscapability' => false,
|
||||
'expected' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a forum instance.
|
||||
*
|
||||
|
||||
@@ -197,6 +197,7 @@ switch ($forum->get_type()) {
|
||||
'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
|
||||
'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
|
||||
'sendstudentnotifications' => $forum->should_notify_students_default_when_grade_for_forum(),
|
||||
'gradeonlyactiveusers' => $forumgradeitem->should_grade_only_active_users(),
|
||||
];
|
||||
echo $OUTPUT->render_from_template('mod_forum/grades/grade_button', $gradeobj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user