Moodle自定义Question Type插件复制课程报数据库记录缺失错误
Moodle自定义题型课程复制后缺失附属表记录修复方案
问题根因
课程复制触发的是Moodle核心的题目备份-还原流程,该流程不会自动同步自定义题型的附属表数据。你当前的插件代码存在两个核心问题:
- 未实现题型类要求的备份导出、还原导入接口方法,备份环节不会导出
qtype_aligator_options表的配置数据,还原环节自然不会为新生成的questionid插入对应附属记录 - 现有方法存在边界逻辑缺陷:
get_question_options强制要求附属表记录存在,还原流程的中间状态会直接触发报错;save_question_options未做字段默认值兼容,导入场景下容易出现字段缺失错误;initialise_question_instance存在属性赋值错误。
修复步骤
1. 修改questiontype.php文件
替换文件中对应方法的实现,补全缺失的备份还原接口,修正现有逻辑缺陷:
/** * 备份时导出题型自定义配置 */ public function export_to_xml($question, qformat_xml $format, $extra = null) { $output = ''; $output .= ' <custom_input>' . $format->writetext($question->options->custom_input) . "</custom_input>\n"; $output .= ' <wkz>' . $format->writetext($question->options->wkz) . "</wkz>\n"; return $output; } /** * 还原/复制时导入题型自定义配置 */ public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { $question->custom_input = $format->getpath($data, ['#', 'custom_input', 0, '#'], ''); $question->wkz = $format->getpath($data, ['#', 'wkz', 0, '#'], 0); return $question; } public function get_question_options($question) { global $DB; $question->options = $DB->get_record( 'qtype_aligator_options', ['questionid' => $question->id] ); // 记录不存在时初始化默认值,避免还原中间态报错 if (!$question->options) { $question->options = new stdClass(); $question->options->custom_input = ''; $question->options->wkz = 0; } parent::get_question_options($question); } public function save_question_options($formdata) { global $DB; $options = $DB->get_record('qtype_aligator_options', ['questionid' => $formdata->id]); if (!$options) { $options = new stdClass(); $options->questionid = $formdata->id; // 提前初始化字段默认值 $options->custom_input = ''; $options->wkz = 0; $options->id = $DB->insert_record('qtype_aligator_options', $options); } // 兼容字段未传值的场景 $options->custom_input = isset($formdata->custom_input) ? $formdata->custom_input : ''; $options->wkz = isset($formdata->wkz) ? $formdata->wkz : 0; $DB->update_record('qtype_aligator_options', $options); } protected function initialise_question_instance(question_definition $question, $questiondata) { parent::initialise_question_instance($question, $questiondata); $question->custom_input = $questiondata->options->custom_input; $question->wkz = $questiondata->options->wkz; $question->formatwkz = $questiondata->options->wkz; }
2. 验证修复
- 进入站点管理→开发→清除所有缓存
- 重新执行课程复制操作,访问新复制课程下的对应题目
- 检查
qtype_aligator_options表,确认已生成关联新questionid的记录,无invalidrecord报错
补充说明
Moodle 3.9已停止官方安全维护,长期使用建议升级到官方支持的LTS版本,减少自定义插件兼容风险。
内容的提问来源于stack exchange,提问作者Eduard Moser
相关产品推荐
相关产品推荐

