public function get_analysables_iterator(?string $action = null) {
        global $DB;

        list($sql, $params) = $this->get_iterator_sql('course', CONTEXT_COURSE, $action, 'c');

        // This will be updated to filter by context as part of MDL-64739.
        if (!empty($this->options['filter'])) {
            $courses = array();
            foreach ($this->options['filter'] as $courseid) {
                $courses[$courseid] = new \stdClass();
                $courses[$courseid]->id = $courseid;
            }

            list($coursesql, $courseparams) = $DB->get_in_or_equal($courses, SQL_PARAMS_NAMED);
            $sql .= " AND c.id IN $coursesql";
            $params = $params + $courseparams;
        }

        $ordersql = $this->order_sql('sortorder', 'ASC', 'c');

        $recordset = $DB->get_recordset_sql($sql . $ordersql, $params);

        if (!$recordset->valid()) {
            $this->add_log(get_string('nocourses', 'analytics'));
            return new \ArrayIterator([]);
        }

        return new \core\dml\recordset_walk($recordset, function($record) {

            if ($record->id == SITEID) {
                return false;
            }
            $context = \context_helper::preload_from_record($record);
            return \core_analytics\course::instance($record, $context);
        });
    }