Moodle v3.11测验结果页通知被覆盖,如何让插件代码生效?
环境信息
- Moodle版本:v3.11
- 操作系统:Windows 10
- 使用主题:classic
问题描述
我需要在测验结果页面展示HTML代码,但发现Moodle会覆盖该页面内容。即使是在其他页面均能正常运行的代码,在测验结果页也无法正常显示。
示例代码:
function local_adaptive_quiz_before_footer(){ error_log('local_adaptive_quiz_before_footer worked'); \core\notification::add('The Local adaptive quiz plugin has been launched! v2', \core\output\notification::NOTIFY_SUCCESS); }
页面加载缓慢时,能看到通知短暂出现后,随页面完全加载而消失。
需求
如何使插件的通知及代码在测验结果页面正常生效?
已尝试的方法
仅查找过课程或测验设置,未找到相关内容清除选项,推测需修改测验模块源码。
解决方案
测验结果页(mod/quiz/review.php)在渲染时会主动调用\core\notification::clear()清除所有会话中的通知,这是页面默认的设计逻辑,目的是只展示测验相关的反馈内容。针对这个问题,给你三个可行的解决思路:
1. 临时修改核心代码(不推荐,升级会失效)
找到mod/quiz/review.php文件,搜索\core\notification::clear()这行代码,把它注释掉或者删除。这样页面就不会清除你通过钩子添加的通知了。但要注意,后续Moodle升级时这个修改会被覆盖,需要每次升级后重新操作。
2. 改用JavaScript动态添加通知(推荐,无核心修改)
放弃直接用PHP添加通知,改用Moodle的AMD JavaScript在页面加载完成后插入通知。修改你的钩子代码如下:
function local_adaptive_quiz_before_footer(){ error_log('local_adaptive_quiz_before_footer worked'); global $PAGE; // 注入JS代码,页面加载完成后添加通知 $PAGE->requires->js_amd_inline(' require([\'core/notification\'], function(Notification) { Notification.addNotification({ message: "The Local adaptive quiz plugin has been launched! v2", type: "success" }); }); '); }
这种方式绕开了PHP层面的通知清除逻辑,因为通知是在页面完全加载后动态创建的,不会被页面的初始化清除操作影响。
3. 利用测验模块的专属钩子(更贴合Moodle规范)
如果你的插件是专门适配测验模块的,可以找到测验结果页的渲染钩子。比如在mod/quiz/renderer.php的render_review_page方法中,在页面输出前添加你的通知代码;或者注册quiz_review_page_before_output事件(Moodle v3.11支持该事件),在事件回调中添加通知,这样通知会在页面渲染的后期添加,不会被提前清除。
内容的提问来源于stack exchange,提问作者Betrayal

