mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
Merge branch 'MDL-74321-master' of https://github.com/junpataleta/moodle
This commit is contained in:
commit
ec0e5ee734
@ -120,7 +120,8 @@ class capability {
|
||||
}
|
||||
|
||||
// If the user reaches the number of posts equal to warning/blocking setting then return the value of canpost in $warningobj.
|
||||
if ($warningobj = forum_check_throttling($this->forumrecord)) {
|
||||
$cmrecord = $this->forum->get_course_module_record();
|
||||
if ($warningobj = forum_check_throttling($this->forumrecord, $cmrecord)) {
|
||||
return $warningobj->canpost;
|
||||
}
|
||||
|
||||
@ -330,7 +331,7 @@ class capability {
|
||||
$status = forum_user_can_post($forumrecord, $discussionrecord, $user, $coursemodule, $course, $context);
|
||||
|
||||
// If the user reaches the number of posts equal to warning/blocking setting then logically and canpost value with $status.
|
||||
if ($warningobj = forum_check_throttling($forumrecord)) {
|
||||
if ($warningobj = forum_check_throttling($forumrecord, $coursemodule)) {
|
||||
return $status && $warningobj->canpost;
|
||||
}
|
||||
return $status;
|
||||
|
@ -236,7 +236,8 @@ class discussion {
|
||||
}
|
||||
|
||||
$exporteddiscussion['throttlingwarningmsg'] = '';
|
||||
if (($warningobj = forum_check_throttling($this->forumrecord)) && $warningobj->canpost) {
|
||||
$cmrecord = $this->forum->get_course_module_record();
|
||||
if (($warningobj = forum_check_throttling($this->forumrecord, $cmrecord)) && $warningobj->canpost) {
|
||||
$throttlewarnnotification = (new notification(
|
||||
get_string($warningobj->errorcode, $warningobj->module, $warningobj->additional)
|
||||
))->set_show_closebutton();
|
||||
|
@ -5038,15 +5038,16 @@ function forum_check_throttling($forum, $cm = null) {
|
||||
global $CFG, $DB, $USER;
|
||||
|
||||
if (is_numeric($forum)) {
|
||||
$forum = $DB->get_record('forum', array('id' => $forum), '*', MUST_EXIST);
|
||||
$forum = $DB->get_record('forum', ['id' => $forum], 'id, course, blockperiod, blockafter, warnafter', MUST_EXIST);
|
||||
}
|
||||
|
||||
if (!is_object($forum)) {
|
||||
return false; // This is broken.
|
||||
}
|
||||
|
||||
if (!$cm) {
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course, false, MUST_EXIST);
|
||||
if (!is_object($forum) || !isset($forum->id) || !isset($forum->course)) {
|
||||
// The passed forum parameter is invalid. This can happen if:
|
||||
// - a non-object and non-numeric forum is passed; or
|
||||
// - the forum object does not have an ID or course attributes.
|
||||
// This is unlikely to happen with properly formed forum record fetched from the database,
|
||||
// so it's most likely a dev error if we hit such this case.
|
||||
throw new coding_exception('Invalid forum parameter passed');
|
||||
}
|
||||
|
||||
if (empty($forum->blockafter)) {
|
||||
@ -5057,6 +5058,22 @@ function forum_check_throttling($forum, $cm = null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$cm) {
|
||||
// Try to fetch the $cm object via get_fast_modinfo() so we don't incur DB reads.
|
||||
$modinfo = get_fast_modinfo($forum->course);
|
||||
$forumcms = $modinfo->get_instances_of('forum');
|
||||
foreach ($forumcms as $tmpcm) {
|
||||
if ($tmpcm->instance == $forum->id) {
|
||||
$cm = $tmpcm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Last resort. Try to fetch via get_coursemodule_from_instance().
|
||||
if (!$cm) {
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course, false, MUST_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
$modcontext = context_module::instance($cm->id);
|
||||
if (has_capability('mod/forum:postwithoutthrottling', $modcontext)) {
|
||||
return false;
|
||||
@ -5096,6 +5113,9 @@ function forum_check_throttling($forum, $cm = null) {
|
||||
|
||||
return $warning;
|
||||
}
|
||||
|
||||
// No warning needs to be shown yet.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
namespace mod_forum;
|
||||
|
||||
use mod_forum_generator;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
@ -4083,4 +4085,180 @@ class lib_test extends \advanced_testcase {
|
||||
$this->assertEquals($expectednormal, forum_get_layout_modes(false));
|
||||
$this->assertEquals($expectedexperimental, forum_get_layout_modes(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for tests that cause forum_check_throttling to return early.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function forum_check_throttling_early_returns_provider() {
|
||||
return [
|
||||
'Empty blockafter' => [(object)['id' => 1, 'course' => SITEID, 'blockafter' => 0]],
|
||||
'Empty blockperiod' => [(object)['id' => 1, 'course' => SITEID, 'blockafter' => DAYSECS, 'blockperiod' => 0]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the early return scenarios of forum_check_throttling.
|
||||
*
|
||||
* @dataProvider forum_check_throttling_early_returns_provider
|
||||
* @covers ::forum_check_throttling
|
||||
* @param \stdClass $forum The forum data.
|
||||
*/
|
||||
public function test_forum_check_throttling_early_returns(\stdClass $forum) {
|
||||
$this->assertFalse(forum_check_throttling($forum));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for tests that cause forum_check_throttling to throw exceptions early.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function forum_check_throttling_early_exceptions_provider() {
|
||||
return [
|
||||
'Non-object forum' => ['a'],
|
||||
'Forum ID not set' => [(object)['id' => false]],
|
||||
'Course ID not set' => [(object)['id' => 1]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the early exception scenarios of forum_check_throttling.
|
||||
*
|
||||
* @dataProvider forum_check_throttling_early_exceptions_provider
|
||||
* @covers ::forum_check_throttling
|
||||
* @param mixed $forum The forum data.
|
||||
*/
|
||||
public function test_forum_check_throttling_early_exceptions($forum) {
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->assertFalse(forum_check_throttling($forum));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests forum_check_throttling when a non-existent numeric ID is passed for its forum parameter.
|
||||
*
|
||||
* @covers ::forum_check_throttling
|
||||
*/
|
||||
public function test_forum_check_throttling_nonexistent_numeric_id() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->expectException(\moodle_exception::class);
|
||||
forum_check_throttling(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests forum_check_throttling when a non-existent forum record is passed for its forum parameter.
|
||||
*
|
||||
* @covers ::forum_check_throttling
|
||||
*/
|
||||
public function test_forum_check_throttling_nonexistent_forum_cm() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$dummyforum = (object)[
|
||||
'id' => 1,
|
||||
'course' => SITEID,
|
||||
'blockafter' => 2,
|
||||
'blockperiod' => DAYSECS,
|
||||
];
|
||||
$this->expectException(\moodle_exception::class);
|
||||
forum_check_throttling($dummyforum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests forum_check_throttling when a user with the 'mod/forum:postwithoutthrottling' capability.
|
||||
*
|
||||
* @covers ::forum_check_throttling
|
||||
*/
|
||||
public function test_forum_check_throttling_teacher() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
$teacher = $generator->create_and_enrol($course, 'teacher');
|
||||
|
||||
/** @var mod_forum_generator $forumgenerator */
|
||||
$forumgenerator = $generator->get_plugin_generator('mod_forum');
|
||||
// Forum that limits students from creating more than two posts per day.
|
||||
$forum = $forumgenerator->create_instance(
|
||||
[
|
||||
'course' => $course->id,
|
||||
'blockafter' => 2,
|
||||
'blockperiod' => DAYSECS,
|
||||
]
|
||||
);
|
||||
|
||||
$this->setUser($teacher);
|
||||
$discussionrecord = [
|
||||
'course' => $course->id,
|
||||
'forum' => $forum->id,
|
||||
'userid' => $teacher->id,
|
||||
];
|
||||
$discussion = $forumgenerator->create_discussion($discussionrecord);
|
||||
// Create a forum post as the teacher.
|
||||
$postrecord = [
|
||||
'userid' => $teacher->id,
|
||||
'discussion' => $discussion->id,
|
||||
];
|
||||
$forumgenerator->create_post($postrecord);
|
||||
// Create another forum post.
|
||||
$forumgenerator->create_post($postrecord);
|
||||
|
||||
$this->assertFalse(forum_check_throttling($forum));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests forum_check_throttling for students.
|
||||
*
|
||||
* @covers ::forum_check_throttling
|
||||
*/
|
||||
public function test_forum_check_throttling_student() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
$student = $generator->create_and_enrol($course, 'student');
|
||||
|
||||
/** @var mod_forum_generator $forumgenerator */
|
||||
$forumgenerator = $generator->get_plugin_generator('mod_forum');
|
||||
// Forum that limits students from creating more than two posts per day.
|
||||
$forum = $forumgenerator->create_instance(
|
||||
[
|
||||
'course' => $course->id,
|
||||
'blockafter' => 2,
|
||||
'blockperiod' => DAYSECS,
|
||||
'warnafter' => 1,
|
||||
]
|
||||
);
|
||||
|
||||
$this->setUser($student);
|
||||
|
||||
// Student hasn't posted yet so no warning will be shown.
|
||||
$throttling = forum_check_throttling($forum);
|
||||
$this->assertFalse($throttling);
|
||||
|
||||
// Create a discussion.
|
||||
$discussionrecord = [
|
||||
'course' => $course->id,
|
||||
'forum' => $forum->id,
|
||||
'userid' => $student->id,
|
||||
];
|
||||
$discussion = $forumgenerator->create_discussion($discussionrecord);
|
||||
|
||||
// A warning will be shown to the student, but they should still be able to post.
|
||||
$throttling = forum_check_throttling($forum);
|
||||
$this->assertIsObject($throttling);
|
||||
$this->assertTrue($throttling->canpost);
|
||||
|
||||
// Create another forum post as the student.
|
||||
$postrecord = [
|
||||
'userid' => $student->id,
|
||||
'discussion' => $discussion->id,
|
||||
];
|
||||
$forumgenerator->create_post($postrecord);
|
||||
|
||||
// Student should now be unable to post after their second post.
|
||||
$throttling = forum_check_throttling($forum);
|
||||
$this->assertIsObject($throttling);
|
||||
$this->assertFalse($throttling->canpost);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user