public static function get_calendar_action_events_by_courses(
        array $courseids, $timesortfrom = null, $timesortto = null, $limitnum = 10) {

        global $PAGE, $USER;

        $user = null;
        $params = self::validate_parameters(
            self::get_calendar_action_events_by_courses_parameters(),
            [
                'courseids' => $courseids,
                'timesortfrom' => $timesortfrom,
                'timesortto' => $timesortto,
                'limitnum' => $limitnum,
            ]
        );
        $context = \context_user::instance($USER->id);
        self::validate_context($context);

        if (empty($params['courseids'])) {
            return ['groupedbycourse' => []];
        }

        $renderer = $PAGE->get_renderer('core_calendar');
        $courses = enrol_get_my_courses('*', null, 0, $params['courseids']);
        $courses = array_values($courses);

        if (empty($courses)) {
            return ['groupedbycourse' => []];
        }

        $events = local_api::get_action_events_by_courses(
            $courses,
            $params['timesortfrom'],
            $params['timesortto'],
            $params['limitnum']
        );

        if (empty($events)) {
            return ['groupedbycourse' => []];
        }

        $exportercache = new events_related_objects_cache($events, $courses);
        $exporter = new events_grouped_by_course_exporter($events, ['cache' => $exportercache]);

        return $exporter->export($renderer);
    }