protected static function get_sql_where_from_contexts(array $contexts) {
        global $DB;

        $sorted = array_reduce($contexts, function ($carry, $context) {
            $level = $context->contextlevel;
            if ($level == CONTEXT_MODULE || $level == CONTEXT_COURSE) {
                $carry[$level][] = $context->instanceid;
            } else if ($level == CONTEXT_SYSTEM) {
                $carry[$level] = $context->id;
            }
            return $carry;
        }, [
            CONTEXT_COURSE => [],
            CONTEXT_MODULE => [],
            CONTEXT_SYSTEM => null,
        ]);

        $sqls = [];
        $params = [];

        if (!empty($sorted[CONTEXT_MODULE])) {
            list($insql, $inparams) = $DB->get_in_or_equal($sorted[CONTEXT_MODULE], SQL_PARAMS_NAMED);
            $sqls[] = "cmid $insql";
            $params = array_merge($params, $inparams);
        }

        if (!empty($sorted[CONTEXT_COURSE])) {
            list($insql, $inparams) = $DB->get_in_or_equal($sorted[CONTEXT_COURSE], SQL_PARAMS_NAMED);

            $sqls[] = "cmid = 0 AND course $insql";
            $params = array_merge($params, $inparams);
        }

        if (!empty($sorted[CONTEXT_SYSTEM])) {
            $sqls[] = "course <= 0";
        }

        if (empty($sqls)) {
            return [null, null];
        }

        return ['((' . implode(') OR (', $sqls) . '))', $params];
    }