警告消息未从 Moodle 中的本地插件返回

warning messages not returning from local plugin in Moodle

我正在尝试通过 API 提取每门课程的完成数据。 通过输入 courseid 提取所有数据和课程数据工作正常,但是当我输入 courseid 在 Moodle 中不存在时,它不会 return 警告消息。

课程 ID 5 不存在,它应该会发出警告消息,但它 return 是一个错误。

看起来它可以识别 $courseid 是否为空,并根据输入的请求显示正确的值。 我查看了其他插件文件,看到其他人是如何在他们的代码中传递警告消息的,它看起来是一样的,我不明白为什么这不会抛出错误消息。 我是否缺少导入 class?

如有任何帮助,我们将不胜感激。

这是我的代码。

class local_get_completion_overview_external extends external_api {

    public static function get_completion_overview_parameters() {
        return new external_function_parameters(
            array(
                'field' => new external_value(PARAM_ALPHA, 'The field to search can be left empty for all courses or:
                    id: course id', VALUE_DEFAULT, ''),
                'value' => new external_value(PARAM_RAW, 'The value to match', VALUE_DEFAULT, '')
            )
        );
    }

    public static function get_completion_overview($field='', $value=''){
        global $CFG, $DB;
        require_once($CFG->dirroot . '/course/lib.php');

        $params = self::validate_parameters(self::get_completion_overview_parameters(),
            array(
                'field' => $field,
                'value' => $value,
            )
        );

        $sql = "SELECT DISTINCT cr.id AS courseid,
                cr.fullname AS coursename,
                COUNT(DISTINCT ra.id ) AS enrols,
                COUNT(DISTINCT cc.timecompleted) AS completed
                FROM {course} cr
                JOIN {context} ct ON ( ct.instanceid = cr.id )
                LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
                LEFT JOIN {course_completions} cc ON cc.course = cr.id
                GROUP BY  cr.fullname, cr.id
                ORDER BY coursename";

        $warnings = array();
        $requestedcourseids = $params['value'];

        if (empty($params['field'])) {
            $courses = $DB->get_records_sql($sql, array());
        } else {
            $value = clean_param($params['id'], PARAM_INT);

            if (count($value) > 0) {
                $placeholders = array();

                $sql_2 = "SELECT DISTINCT cr.id AS courseid, 
                            cr.fullname AS coursename, 
                            COUNT(DISTINCT ra.id) AS enrols, 
                            COUNT(DISTINCT cc.timecompleted) AS completed 
                            FROM {course} cr JOIN {context} ct ON ( ct.instanceid = cr.id ) 
                            LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5 
                            LEFT JOIN {course_completions} cc ON (cc.course = cr.id) 
                            WHERE cr.id = ".$requestedcourseids." GROUP BY cr.fullname, cr.id";

                $courses = $DB->get_records_sql($sql_2, $placeholders);
            }
        }

        if(!empty($courses)) {

            $coursesdata = array();
            $currentcourseid = null;
            $course = null;

            foreach($courses as $completion) {
                $context = context_system::instance();
                has_capability('moodle/site:config', $context);

                if(is_null($currentcourseid) || ($completion->courseid != $currentcourseid)) {
                    if(!is_null($course)) {
                        $coursesdata[] = $course;
                    }
                    $course = array();
                    $course['courseid'] = $completion->courseid;
                    $course['coursename'] = $completion->coursename;
                    $course['enrols'] = $completion->enrols;
                    $course['completed'] = $completion->completed;
                    $course['totalcourses'] = count($course);

                }

                $currentcourseid = $completion->courseid;
            }

            if(!is_null($course)){
                $coursesdata[] = $course;
            }

        } else {
            $warning = array();
            $warning['item'] = 'course';
            $warning['itemid'] = $requestedcourseids;
            $warning['warningcode'] = '1';
            $warning['message'] = 'No course found';

            $warnings[] = $warning;
        }

        $result['course'] = $coursesdata;
        $result['warnings'] = $warnings;

        return $result;
    }

    public static function get_completion_overview_returns() {
        return new external_single_structure(
            array(
                'course' => new external_multiple_structure(
                    new external_single_structure(
                        array(
                            'courseid' => new external_value(PARAM_INT, 'description'),
                            'coursename' => new external_value(PARAM_TEXT, ''),
                            'enrols' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
                            'completed' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
                            'totalcourses' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
                        )
                    )
                ),
                'warnings' => new external_warnings()
            )
        );
    }
}

在您的代码中,只有在数据库中找到至少一门请求的课程时,变量 $coursesdata 才会被初始化为一个数组。

因此,行:

$result['courses'] = $coursesdata;

将产生一条警告消息(如果调试已打开)并将 $result['courses'] 设置为空。这里的预期类型是一个数组,因此 web 服务代码正确地抱怨 'courses' 值不是正确的类型。

要修复,请确保添加:

$coursesdata = [];

函数顶部附近的某个位置。