Moodle 3.11自定义活动删除确认对话框及删除反馈问题
解决Moodle 3.11活动模块删除的两个问题
一、自定义删除确认对话框
方法1:直接覆盖语言字符串
Moodle删除活动时的确认提示字符串标识为deletechecktypename,你可以在模块的语言文件中重新定义该字符串,替换默认提示:
- 在模块目录的
lang/en/下创建或编辑myactivity.php(替换为你的模块名),添加:
$string['deletechecktypename'] = '确认:您确定要删除活动"{$a}"吗?删除后该活动关联的所有用户条目也将被一并删除。';
- 若需要多语言支持,在对应语言的子目录下添加相同的字符串定义。
这种方法简单直接,适合静态提示内容的场景。
方法2:自定义JS对话框(支持动态内容)
如果需要显示动态信息(比如关联用户条目数量),可以通过JS覆盖默认的确认逻辑:
- 在模块的
amd/src/目录下创建deleteconfirm.js,内容如下:
define(['core/modal_factory', 'core/modal_events', 'core/ajax', 'core/notification'], function(ModalFactory, ModalEvents, Ajax, Notification) { var init = function() { // 匹配模块删除链接,根据实际页面结构调整选择器 const deleteLinks = document.querySelectorAll('a[href*="delete.php?id="]'); deleteLinks.forEach(link => { link.addEventListener('click', e => { e.preventDefault(); const instanceId = link.href.match(/id=(\d+)/)[1]; // 调用AJAX获取关联用户条目数量 Ajax.call([{ methodname: 'mod_myactivity_get_user_entries_count', args: {instanceid: instanceId}, done: count => { const confirmMsg = `确认:您确定要删除该活动吗?删除后将一并删除${count}条用户关联条目。`; // 创建自定义确认弹窗 ModalFactory.create({ type: ModalFactory.types.SAVE_CANCEL, title: '确认删除', body: confirmMsg }).then(modal => { modal.show(); // 确认后执行删除跳转 modal.getRoot().on(ModalEvents.save, () => { window.location.href = link.href; }); }).catch(Notification.exception); }, fail: Notification.exception }]); }); }); }; return {init: init}; });
- 在模块的
lib.php中添加函数,确保JS在需要的页面加载:
function myactivity_before_standard_html_head() { global $PAGE; // 仅在模块删除页面加载JS if ($PAGE->context->contextlevel == CONTEXT_MODULE && strpos($PAGE->url->out(), 'delete.php') !== false) { $PAGE->requires->js_call_amd('mod_myactivity/deleteconfirm', 'init'); } }
- 创建对应的Web服务函数(可选,若需要动态数据):
在db/services.php中注册服务:
$functions = [ 'mod_myactivity_get_user_entries_count' => [ 'classname' => 'mod_myactivity_external', 'methodname' => 'get_user_entries_count', 'classpath' => 'mod/myactivity/externallib.php', 'description' => 'Get count of user entries for a myactivity instance', 'type' => 'read', 'capabilities'=> 'mod/myactivity:manage', ], ];
然后在externallib.php中实现:
class mod_myactivity_external extends external_api { public static function get_user_entries_count_parameters() { return new external_function_parameters([ 'instanceid' => new external_value(PARAM_INT, 'Myactivity instance ID'), ]); } public static function get_user_entries_count($instanceid) { global $DB; $params = self::validate_parameters(self::get_user_entries_count_parameters(), ['instanceid' => $instanceid]); require_capability('mod/myactivity:manage', context_module::instance($params['instanceid'])); return $DB->count_records('myactivity_user_entries', ['myactivityid' => $params['instanceid']]); } public static function get_user_entries_count_returns() { return new external_value(PARAM_INT, 'Count of user entries'); } }
二、即时显示删除操作的错误通知
在lib.php的myactivity_delete_instance()函数中,不要直接返回false(会抛出系统错误),而是通过redirect()跳回原页面并携带错误通知:
function myactivity_delete_instance($id) { global $DB, $CFG; $instance = $DB->get_record('myactivity', ['id' => $id], '*', MUST_EXIST); // 检查删除条件,示例:存在无法删除的用户条目 $userEntryCount = $DB->count_records('myactivity_user_entries', ['myactivityid' => $id]); if ($userEntryCount > 0) { // 自定义禁止删除的条件 $errorMsg = '无法删除该活动:仍有用户关联条目存在,请先清理后再尝试删除。'; // 跳回课程页面并显示错误通知 require_once($CFG->libdir . '/moodlelib.php'); redirect( new moodle_url('/course/view.php', ['id' => $instance->course]), $errorMsg, null, \core\output\notification::NOTIFY_ERROR ); return false; // redirect已终止脚本,此处仅为语法完整 } // 执行正常删除逻辑 if (!$DB->delete_records('myactivity', ['id' => $id])) { return false; } $DB->delete_records('myactivity_user_entries', ['myactivityid' => $id]); // 删除模块相关文件 $fs = get_file_storage(); $fs->delete_area_files(context_module::instance($id)->id, 'mod_myactivity'); return true; }
这样操作后,当删除被阻止时,会立即跳回课程页面并显示错误通知,无需刷新。
内容的提问来源于stack exchange,提问作者Frank Walter
相关产品推荐
相关产品推荐

