protected static function get_nested_expiry_info_for_courses($contextpath = '') : array {
        global $DB;

        $contextfields = \context_helper::get_preload_record_columns_sql('ctx');
        $expiredfields = expired_context::get_sql_fields('expiredctx', 'expiredctx');
        $purposefields = 'dpctx.purposeid';
        $coursefields = 'ctxcourse.expirydate AS expirydate';
        $fields = implode(', ', ['ctx.id', $contextfields, $expiredfields, $coursefields, $purposefields]);

        // We want all contexts at course-dependant levels.
        $parentpath = $DB->sql_concat('ctxcourse.path', "'/%'");

        // This SQL query returns all course-dependant contexts (including the course context)
        // which course end date already passed.
        // This is ordered by the context path in reverse order, which will give the child nodes before any parent node.
        $params = [
            'contextlevel' => CONTEXT_COURSE,
        ];
        $where = '';

        if (!empty($contextpath)) {
            $where = "WHERE (ctx.path = :pathmatchexact OR ctx.path LIKE :pathmatchchildren)";
            $params['pathmatchexact'] = $contextpath;
            $params['pathmatchchildren'] = "{$contextpath}/%";
        }

        $sql = "SELECT $fields
                  FROM {context} ctx
                  JOIN (
                        SELECT c.enddate AS expirydate, subctx.path
                          FROM {context} subctx
                          JOIN {course} c
                            ON subctx.contextlevel = :contextlevel
                           AND subctx.instanceid = c.id
                           AND c.format != 'site'
                       ) ctxcourse
                    ON ctx.path LIKE {$parentpath} OR ctx.path = ctxcourse.path
             LEFT JOIN {tool_dataprivacy_ctxinstance} dpctx
                    ON dpctx.contextid = ctx.id
             LEFT JOIN {tool_dataprivacy_ctxexpired} expiredctx
                    ON ctx.id = expiredctx.contextid
                 {$where}
              ORDER BY ctx.path DESC";

        return self::get_nested_expiry_info_from_sql($sql, $params);
    }