Moodle课程模块增改时Observer未触发问题求助
Moodle课程模块事件观察者失效排查求助
在Moodle中尝试为course_module_updated和course_module_created事件添加Observer,但所有触发验证方式均未生效。已尝试清理全部缓存、写入文件日志、写入数据库日志、die()终止程序,均无效果。
疑问:是我的代码存在错误?还是事件已触发但日志代码未正常工作?
相关代码
db/events.php
defined('MOODLE_INTERNAL') || die(); use moodle_local_plugin\event\events_observer; $observers = [ [ 'eventname' => '\core\event\course_module_updated', 'callback' => 'events_observer::course_module_updated', 'includefile' => null, 'internal' => true, 'priority' => 9999 ], [ 'eventname' => '\core\event\course_module_created', 'callback' => 'events_observer::course_module_updated', 'includefile' => null, 'internal' => true, 'priority' => 9999 ], ];
classes/event/observer.php
namespace moodle_local_plugin\event; defined('MOODLE_INTERNAL') || die(); class events_observer { /** * Triggered when 'course_module_updated' event is triggered. * * @param \core\event\course_module_updated $event * @return bool */ public static function course_module_updated(\core\event\course_module_updated $event) { global $DB, $CFG; // Log to DB $logdata = new \stdClass(); $logdata->eventname = $event->eventname; $logdata->component = 'local_course_editor'; $logdata->action = 'updated'; $logdata->target = 'course_module'; $logdata->objectid = $event->objectid; $logdata->timecreated = time(); $DB->insert_record('log', $logdata); // Log the event data to a file $logfile = $CFG->dirroot . '/local/moodle_local_plugin/log.txt'; $timestamp = date('Y-m-d H:i:s'); $eventData = json_encode($event->get_data(), JSON_PRETTY_PRINT); $logMessage = "[{$timestamp}] Course module updated: {$eventData} "; file_put_contents($logfile, $logMessage, FILE_APPEND); // end die(var_dump($event)); // return true; } }
排查关键点
- 命名空间与插件目录不匹配:
观察者类命名空间为moodle_local_plugin\event,但日志中component写的是local_course_editor,如果插件实际目录是local/course_editor,则命名空间应改为local_course_editor\event,同时events.php中的use语句和回调路径也需同步修改,否则Moodle自动加载找不到类。 - 事件回调参数类型不兼容:
course_module_created事件的回调指定了course_module_updated方法,但该方法的参数类型是\core\event\course_module_updated,与实际触发的course_module_created事件类型不匹配,会触发PHP类型错误,导致观察者被静默跳过。 - 数据库日志表字段缺失:
直接往log表插入数据,但log表存在userid、contextid等必填字段,当前插入的$logdata缺少这些字段,会导致数据库插入失败,触发异常后后续代码(包括文件日志、die())都不会执行。 - 文件日志路径错误:
日志文件路径写的是/local/moodle_local_plugin/log.txt,如果插件目录不是moodle_local_plugin,则路径无效,且需确保该目录有写入权限,否则file_put_contents执行失败。 - 调试模式未开启:
未开启Moodle调试模式的话,PHP错误会被静默捕获,无法看到观察者执行过程中的报错信息。
修复建议
- 确认插件目录名,修正命名空间与
events.php中的use语句,保证命名空间与文件路径严格对应(Moodle自动加载规则:classes/event/observer.php对应local_插件名\event\events_observer)。 - 为
course_module_created事件单独编写回调方法,或修改现有方法参数为\core\event\base $event以兼容所有事件类型。 - 改用Moodle自带的
add_to_log()函数记录日志,或补充log表所需的所有必填字段后再执行插入。 - 修正文件日志路径为插件实际目录,确保目录存在且服务器有写入权限。
- 在
config.php中开启调试模式:
开启后可直接看到执行过程中的错误信息。$CFG->debug = E_ALL; $CFG->debugdisplay = true; - 清理缓存后,重新触发课程模块的创建/更新操作,验证观察者是否生效。
内容的提问来源于stack exchange,提问作者user23275506
相关产品推荐
相关产品推荐

