Skip to content

Commit

Permalink
MDL-79930 mod_forum: Use MUC for forum count discussions
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusboon committed Jan 28, 2024
1 parent 6080ef9 commit 800acd2
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 13 deletions.
9 changes: 9 additions & 0 deletions mod/forum/db/caches.php
Expand Up @@ -32,4 +32,13 @@
'simpledata' => true,
'staticacceleration' => true
],
'forum_count_discussions' => [
'mode' => cache_store::MODE_REQUEST,
'simplekeys' => true,
'simpledata' => true,
'staticacceleration' => true,
'invalidationevents' => [
'changesinforumdiscussions',
],
],
];
1 change: 1 addition & 0 deletions mod/forum/lang/en/forum.php
Expand Up @@ -62,6 +62,7 @@
$string['blockperioddisabled'] = 'Don\'t block';
$string['blogforum'] = 'Standard forum displayed in a blog-like format';
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
$string['cachedef_forum_count_discussions'] = 'Forum discussions count';
$string['cachedef_forum_is_tracked'] = 'Forum tracking status for user';
$string['calendardue'] = '{$a} is due';
$string['cancelreply'] = 'Cancel reply';
Expand Down
35 changes: 23 additions & 12 deletions mod/forum/lib.php
Expand Up @@ -1495,7 +1495,6 @@ function forum_count_discussion_replies($forumid, $forumsort = "", $limit = -1,
* @global object
* @global object
* @global object
* @staticvar array $cache
* @param object $forum
* @param object $cm
* @param object $course
Expand All @@ -1504,13 +1503,21 @@ function forum_count_discussion_replies($forumid, $forumsort = "", $limit = -1,
function forum_count_discussions($forum, $cm, $course) {
global $CFG, $DB, $USER;

static $cache = array();
$cache = cache::make('mod_forum', 'forum_count_discussions');
$cachedcounts = $cache->get($course->id);
if ($cachedcounts === false) {
$cachedcounts = [];
}

$now = floor(time() / 60) * 60; // DB Cache Friendly.

$params = array($course->id);

if (!isset($cache[$course->id])) {
if (!isset($cachedcounts[$forum->id])) {
// Initialize the cachedcounts for this forum id to 0 by default. After the
// database query, if there are discussions then it should update the count.
$cachedcounts[$forum->id] = 0;

if (!empty($CFG->forum_enabletimedposts)) {
$timedsql = "AND d.timestart < ? AND (d.timeend = 0 OR d.timeend > ?)";
$params[] = $now;
Expand All @@ -1528,26 +1535,24 @@ function forum_count_discussions($forum, $cm, $course) {

if ($counts = $DB->get_records_sql($sql, $params)) {
foreach ($counts as $count) {
$counts[$count->id] = $count->dcount;
$cachedcounts[$count->id] = $count->dcount;
}
$cache[$course->id] = $counts;

$cache->set($course->id, $cachedcounts);
} else {
$cache[$course->id] = array();
$cache->set($course->id, $cachedcounts);
return $cachedcounts[$forum->id];
}
}

if (empty($cache[$course->id][$forum->id])) {
return 0;
}

$groupmode = groups_get_activity_groupmode($cm, $course);

if ($groupmode != SEPARATEGROUPS) {
return $cache[$course->id][$forum->id];
return $cachedcounts[$forum->id];
}

if (has_capability('moodle/site:accessallgroups', context_module::instance($cm->id))) {
return $cache[$course->id][$forum->id];
return $cachedcounts[$forum->id];
}

require_once($CFG->dirroot.'/course/lib.php');
Expand Down Expand Up @@ -3113,6 +3118,9 @@ function forum_add_discussion($discussion, $mform=null, $unused=null, $userid=nu
forum_trigger_content_uploaded_event($post, $cm, 'forum_add_discussion');
}

// Clear the discussion count cache just in case it's in the same request.
\cache_helper::purge_by_event('changesinforumdiscussions');

return $post->discussion;
}

Expand Down Expand Up @@ -3173,6 +3181,9 @@ function forum_delete_discussion($discussion, $fulldelete, $course, $cm, $forum)
$event->add_record_snapshot('forum_discussions', $discussion);
$event->trigger();

// Clear the discussion count cache just in case it's in the same request.
\cache_helper::purge_by_event('changesinforumdiscussions');

return $result;
}

Expand Down
83 changes: 83 additions & 0 deletions mod/forum/tests/lib_test.php
Expand Up @@ -4291,4 +4291,87 @@ public function test_forum_check_throttling_student() {
$this->assertIsObject($throttling);
$this->assertFalse($throttling->canpost);
}

/**
* Tests forum_count_discussions.
*
* @covers ::forum_count_discussions
*/
public function test_forum_count_discussions(): void {
$this->resetAfterTest();

$generator = $this->getDataGenerator();
$forumgenerator = $generator->get_plugin_generator('mod_forum');
$course1 = $generator->create_course();
$course2 = $generator->create_course();
$student = $generator->create_user(['trackforums' => 1]);

// First forum.
$forumobj1 = new \stdClass();
$forumobj1->introformat = FORMAT_HTML;
$forumobj1->course = $course1->id;
$forumobj1->trackingtype = FORUM_TRACKING_FORCED;
$forum1 = $generator->create_module('forum', $forumobj1);
$forum1cm = get_coursemodule_from_id('forum', $forum1->cmid, 0, false, MUST_EXIST);

// Second forum.
$forumobj2 = new \stdClass();
$forumobj2->introformat = FORMAT_HTML;
$forumobj2->course = $course2->id;
$forumobj2->trackingtype = FORUM_TRACKING_OFF;
$forum2 = $generator->create_module('forum', $forumobj2);
$forum2cm = get_coursemodule_from_id('forum', $forum2->cmid, 0, false, MUST_EXIST);

// Third forum.
$forumobj3 = new \stdClass();
$forumobj3->introformat = FORMAT_HTML;
$forumobj3->course = $course2->id;
$forumobj3->trackingtype = FORUM_TRACKING_OFF;
$forum3 = $generator->create_module('forum', $forumobj3);
$forum3cm = get_coursemodule_from_id('forum', $forum3->cmid, 0, false, MUST_EXIST);

// First make sure there are no discussions for any of the forums.
$f1discussionscount = forum_count_discussions($forum1, $forum1cm, $course1);
$this->assertEquals(0, $f1discussionscount);
$f2discussionscount = forum_count_discussions($forum2, $forum2cm, $course2);
$this->assertEquals(0, $f2discussionscount);
$f3discussionscount = forum_count_discussions($forum3, $forum3cm, $course2);
$this->assertEquals(0, $f3discussionscount);

// Add 3 discussions to forum 1.
$discussionobj1 = new \stdClass();
$discussionobj1->course = $course1->id;
$discussionobj1->userid = $student->id;
$discussionobj1->forum = $forum1->id;
$forumgenerator->create_discussion($discussionobj1);
$forumgenerator->create_discussion($discussionobj1);
$forumgenerator->create_discussion($discussionobj1);

// Make sure there are 3 discussions.
$f1discussionscount = forum_count_discussions($forum1, $forum1cm, $course1);
$this->assertEquals(3, $f1discussionscount);

// Add 4 discussions to forum 2.
$discussionobj2 = new \stdClass();
$discussionobj2->course = $course2->id;
$discussionobj2->userid = $student->id;
$discussionobj2->forum = $forum2->id;
$forumgenerator->create_discussion($discussionobj2);
$forumgenerator->create_discussion($discussionobj2);
$forumgenerator->create_discussion($discussionobj2);
$discussion24 = $forumgenerator->create_discussion($discussionobj2);

// Make sure there are 4 discussions.
$f2discussionscount = forum_count_discussions($forum2, $forum2cm, $course2);
$this->assertEquals(4, $f2discussionscount);

// Delete one discussion from forum 2.
forum_delete_discussion($discussion24, true, $course2, $forum2cm, $forum2);
$f2discussionscount = forum_count_discussions($forum2, $forum2cm, $course2);
$this->assertEquals(3, $f2discussionscount);

// Make sure there are no discussions.
$f3discussionscount = forum_count_discussions($forum3, $forum3cm, $course2);
$this->assertEquals(0, $f3discussionscount);
}
}
2 changes: 1 addition & 1 deletion mod/forum/version.php
Expand Up @@ -24,6 +24,6 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2023100900; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2023100901; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2023100400; // Requires this Moodle version.
$plugin->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)

0 comments on commit 800acd2

Please sign in to comment.