mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 08:22:07 +02:00
Merge branch 'MDL-83185-main' of https://github.com/laurentdavid/moodle
This commit is contained in:
commit
a97260296d
8
.upgradenotes/MDL-83185-2024103109015923.yml
Normal file
8
.upgradenotes/MDL-83185-2024103109015923.yml
Normal file
@ -0,0 +1,8 @@
|
||||
issueNumber: MDL-83185
|
||||
notes:
|
||||
core_courseformat:
|
||||
- message: >-
|
||||
Add core_courseformat\base::invalidate_all_session_caches to reset course editor cache for all users when course is changed.
|
||||
This method can be used as an alternative to core_courseformat\base::session_cache_reset for resetting the cache for the current user
|
||||
in case the change in the course should be reflected for all users.
|
||||
type: improved
|
@ -283,6 +283,20 @@ abstract class base {
|
||||
return self::session_cache_reset($course);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prune a course state cache for all open sessions.
|
||||
*
|
||||
* Most course edits does not require to invalidate the cache for all users
|
||||
* because the cache relies on the course cacherev value. However, there are
|
||||
* actions like editing the groups that do not change the course cacherev.
|
||||
*
|
||||
* @param \stdClass $course
|
||||
* @return void
|
||||
*/
|
||||
public static function invalidate_all_session_caches_for_course(stdClass $course): void {
|
||||
\cache_helper::invalidate_by_event('changesincoursestate', [$course->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the format name used by this course
|
||||
*
|
||||
|
55
course/format/classes/hook_listener.php
Normal file
55
course/format/classes/hook_listener.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?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/>.
|
||||
|
||||
namespace core_courseformat;
|
||||
|
||||
use core_group\hook\after_group_membership_added;
|
||||
use core_group\hook\after_group_membership_removed;
|
||||
|
||||
/**
|
||||
* Hook listener for course format
|
||||
*
|
||||
* @package core_courseformat
|
||||
* @copyright 2024 Laurent David <laurent.david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class hook_listener {
|
||||
/**
|
||||
* Add members to group room when a new member is added to the group.
|
||||
*
|
||||
* @param after_group_membership_added $hook The group membership added hook.
|
||||
*/
|
||||
public static function add_members_to_group(
|
||||
after_group_membership_added $hook,
|
||||
): void {
|
||||
$group = $hook->groupinstance;
|
||||
$course = get_course($group->courseid);
|
||||
base::invalidate_all_session_caches_for_course($course);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove members from the room when a member is removed from group room.
|
||||
*
|
||||
* @param after_group_membership_removed $hook The group membership removed hook.
|
||||
*/
|
||||
public static function remove_members_from_group(
|
||||
after_group_membership_removed $hook,
|
||||
): void {
|
||||
$group = $hook->groupinstance;
|
||||
$course = get_course($group->courseid);
|
||||
base::invalidate_all_session_caches_for_course($course);
|
||||
}
|
||||
}
|
@ -996,6 +996,84 @@ class base_test extends advanced_testcase {
|
||||
$this->assertFalse($format->is_section_visible($modinfostudent->get_section_info(1)));
|
||||
$this->assertFalse($format->is_section_visible($modinfostudent->get_section_info(2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test can_sections_be_removed_from_navigation().
|
||||
*
|
||||
* @covers ::session_cache
|
||||
* @covers ::session_cache_reset
|
||||
* @covers ::session_cache_reset_all
|
||||
* @covers ::invalidate_all_session_caches_for_course
|
||||
*/
|
||||
public function test_session_caches_methods(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$generator = $this->getDataGenerator();
|
||||
|
||||
$course1 = $generator->create_course(['format' => 'topics']);
|
||||
$course2 = $generator->create_course(['format' => 'topics']);
|
||||
|
||||
// Force some cacherev to the course.
|
||||
$course1->cacherev = 12345;
|
||||
$course2->cacherev = 67890;
|
||||
$DB->set_field('course', 'cacherev', $course1->cacherev, ['id' => $course1->id]);
|
||||
$DB->set_field('course', 'cacherev', $course2->cacherev, ['id' => $course2->id]);
|
||||
|
||||
$teacher = $generator->create_and_enrol($course1, 'editingteacher');
|
||||
$generator->enrol_user($teacher->id, $course2->id, 'editingteacher');
|
||||
$this->setUser($teacher);
|
||||
|
||||
// The cache key uses time() as hash. To not wait a second between calls we fake an initial value.
|
||||
$statecache = cache::make('core', 'courseeditorstate');
|
||||
$statecache->set($course1->id, $course1->cacherev . '_11111');
|
||||
$statecache->set($course2->id, $course2->cacherev . '_22222');
|
||||
|
||||
$course1cachekey = \core_courseformat\base::session_cache($course1);
|
||||
|
||||
// Validate the method returns the same value when called twice.
|
||||
$course1cachekeyagain = \core_courseformat\base::session_cache($course1);
|
||||
$this->assertEquals($course1cachekey, $course1cachekeyagain);
|
||||
|
||||
// Validate other course has a diferent cache key.
|
||||
$course2cachekey = \core_courseformat\base::session_cache($course2);
|
||||
$this->assertNotEquals($course1cachekey, $course2cachekey);
|
||||
|
||||
// Reset the specific course cache.
|
||||
\core_courseformat\base::session_cache_reset($course1);
|
||||
|
||||
$resetcachekey = \core_courseformat\base::session_cache($course1);
|
||||
$this->assertNotEquals($course1cachekey, $resetcachekey);
|
||||
|
||||
$reset2cachekey = \core_courseformat\base::session_cache($course2);
|
||||
$this->assertEquals($course2cachekey, $reset2cachekey);
|
||||
|
||||
// Return to the initial value.
|
||||
$statecache->set($course1->id, $course1->cacherev . '_11111');
|
||||
$statecache->set($course2->id, $course2->cacherev . '_22222');
|
||||
|
||||
// Reset all user course caches.
|
||||
\core_courseformat\base::session_cache_reset_all();
|
||||
|
||||
$resetallcachekey = \core_courseformat\base::session_cache($course1);
|
||||
$this->assertNotEquals($course1cachekey, $resetallcachekey);
|
||||
|
||||
$resetall2cachekey = \core_courseformat\base::session_cache($course2);
|
||||
$this->assertNotEquals($course2cachekey, $resetall2cachekey);
|
||||
|
||||
// Return to the initial value.
|
||||
$statecache->set($course1->id, $course1->cacherev . '_11111');
|
||||
$statecache->set($course2->id, $course2->cacherev . '_22222');
|
||||
|
||||
// Invalidate cache on course 1.
|
||||
\core_courseformat\base::invalidate_all_session_caches_for_course($course1);
|
||||
|
||||
$invalidatecachekey = \core_courseformat\base::session_cache($course1);
|
||||
$this->assertNotEquals($course1cachekey, $invalidatecachekey);
|
||||
|
||||
$invalidate2cachekey = \core_courseformat\base::session_cache($course2);
|
||||
$this->assertEquals($course2cachekey, $invalidate2cachekey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,6 +239,9 @@ $definitions = array(
|
||||
'mode' => cache_store::MODE_SESSION,
|
||||
'simplekeys' => true,
|
||||
'simpledata' => true,
|
||||
'invalidationevents' => [
|
||||
'changesincoursestate',
|
||||
],
|
||||
],
|
||||
// Course actions instances cache.
|
||||
'courseactionsinstances' => [
|
||||
|
@ -45,6 +45,14 @@ $callbacks = [
|
||||
'hook' => \core_group\hook\after_group_membership_removed::class,
|
||||
'callback' => \core_communication\hook_listener::class . '::remove_members_from_group_room',
|
||||
],
|
||||
[
|
||||
'hook' => \core_group\hook\after_group_membership_added::class,
|
||||
'callback' => \core_courseformat\hook_listener::class . '::add_members_to_group',
|
||||
],
|
||||
[
|
||||
'hook' => \core_group\hook\after_group_membership_removed::class,
|
||||
'callback' => \core_courseformat\hook_listener::class . '::remove_members_from_group',
|
||||
],
|
||||
[
|
||||
'hook' => \core_course\hook\after_course_created::class,
|
||||
'callback' => \core_communication\hook_listener::class . '::create_course_communication',
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2024110800.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2024110800.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '5.0dev (Build: 20241108)'; // Human-friendly version name
|
||||
|
Loading…
x
Reference in New Issue
Block a user