You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Moodle 3.11自定义活动删除确认对话框及删除反馈问题

解决Moodle 3.11活动模块删除的两个问题

一、自定义删除确认对话框

方法1:直接覆盖语言字符串

Moodle删除活动时的确认提示字符串标识为deletechecktypename,你可以在模块的语言文件中重新定义该字符串,替换默认提示:

  1. 在模块目录的lang/en/下创建或编辑myactivity.php(替换为你的模块名),添加:
$string['deletechecktypename'] = '确认:您确定要删除活动"{$a}"吗?删除后该活动关联的所有用户条目也将被一并删除。';
  1. 若需要多语言支持,在对应语言的子目录下添加相同的字符串定义。

这种方法简单直接,适合静态提示内容的场景。

方法2:自定义JS对话框(支持动态内容)

如果需要显示动态信息(比如关联用户条目数量),可以通过JS覆盖默认的确认逻辑:

  1. 在模块的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};
});
  1. 在模块的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');
    }
}
  1. 创建对应的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:45:41