예제 #1
0
    /**
     * Return all courses this rule applies to.
     *
     * @return array A list of courses.
     */
    public function get_courses()
    {
        global $CFG, $DB;
        if (isset($this->courses)) {
            return $this->courses;
        }
        require_once $CFG->libdir . '/coursecatlib.php';
        $coursecat = \coursecat::get($this->id);
        $courselist = $coursecat->get_courses(array('recursive' => true, 'idonly' => true));
        // Generate the SQL.
        list($sql, $params) = $DB->get_in_or_equal($courselist);
        $ctxlevel = \CONTEXT_COURSE;
        $preload = \context_helper::get_preload_record_columns_sql('ctx');
        $sql = <<<SQL
            SELECT c.*, {$preload}
            FROM {course} c
            INNER JOIN {context} ctx
                ON ctx.instanceid = c.id AND ctx.contextlevel = {$ctxlevel}
            WHERE c.id {$sql}
SQL;
        // Get the courses and preload contexts.
        $this->courses = $DB->get_records_sql($sql, $params);
        foreach ($this->courses as $course) {
            \context_helper::preload_from_record($course);
        }
        return $this->courses;
    }
예제 #2
0
파일: locallib.php 프로젝트: JP-Git/moodle
/**
 * Returns shortname of activities in course
 *
 * @param int $courseid id of course for which activity shortname is needed
 * @return string|bool list of child shortname
 */
function block_course_overview_get_child_shortnames($courseid)
{
    global $DB;
    $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
    $sql = "SELECT c.id, c.shortname, {$ctxselect}\n            FROM {enrol} e\n            JOIN {course} c ON (c.id = e.customint1)\n            JOIN {context} ctx ON (ctx.instanceid = e.customint1)\n            WHERE e.courseid = :courseid AND e.enrol = :method AND ctx.contextlevel = :contextlevel ORDER BY e.sortorder";
    $params = array('method' => 'meta', 'courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
    if ($results = $DB->get_records_sql($sql, $params)) {
        $shortnames = array();
        // Preload the context we will need it to format the category name shortly.
        foreach ($results as $res) {
            context_helper::preload_from_record($res);
            $context = context_course::instance($res->id);
            $shortnames[] = format_string($res->shortname, true, $context);
        }
        $total = count($shortnames);
        $suffix = '';
        if ($total > 10) {
            $shortnames = array_slice($shortnames, 0, 10);
            $diff = $total - count($shortnames);
            if ($diff > 1) {
                $suffix = get_string('shortnamesufixprural', 'block_course_overview', $diff);
            } else {
                $suffix = get_string('shortnamesufixsingular', 'block_course_overview', $diff);
            }
        }
        $shortnames = get_string('shortnameprefix', 'block_course_overview', implode('; ', $shortnames));
        $shortnames .= $suffix;
    }
    return isset($shortnames) ? $shortnames : false;
}
    public function definition()
    {
        global $CFG, $DB;
        $mform = $this->_form;
        $course = $this->_customdata['course'];
        $instance = $this->_customdata['instance'];
        $this->course = $course;
        $existing = array();
        if ($instance) {
            $existing = $DB->get_records('enrol_metaplus', array('enrolid' => $instance->id), '', 'courseid, id');
        }
        $courses = array();
        $select = context_helper::get_preload_record_columns_sql('ctx');
        $sql = <<<SQL
            SELECT c.id, c.fullname, c.shortname, c.visible, {$select}
            FROM {course} c
            LEFT JOIN {context} ctx
                ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)
SQL;
        $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE));
        foreach ($rs as $c) {
            if ($c->id == SITEID || $c->id == $course->id) {
                continue;
            }
            context_helper::preload_from_record($c);
            $coursecontext = context_course::instance($c->id);
            if (!$c->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
                continue;
            }
            if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
                continue;
            }
            $courses[$c->id] = $coursecontext->get_context_name(false);
        }
        $rs->close();
        $mform->addElement('header', 'general', get_string('pluginname', 'enrol_meta'));
        $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_metaplus'), $courses, array('multiple' => 'multiple', 'class' => 'chosen'));
        $mform->addRule('link', get_string('required'), 'required', null, 'server');
        // Add role sync list.
        $coursecontext = \context_course::instance($course->id);
        $roles = get_assignable_roles($coursecontext);
        $mform->addElement('select', 'roleexclusions', get_string('roleexclusions', 'enrol_metaplus'), $roles, array('multiple' => 'multiple'));
        $mform->addElement('hidden', 'id', null);
        $mform->setType('id', PARAM_INT);
        $mform->addElement('hidden', 'enrolid');
        $mform->setType('enrolid', PARAM_INT);
        $data = array('id' => $course->id);
        if ($instance) {
            $data['link'] = implode(',', array_keys($existing));
            $data['enrolid'] = $instance->id;
            $data['roleexclusions'] = $instance->customtext1;
            $this->add_action_buttons();
        } else {
            $this->add_add_buttons();
        }
        $this->set_data($data);
    }
예제 #4
0
 /**
  * Return the courses where both competency and user are.
  *
  * A user is considered being in a course when they are enrolled, the enrolment is valid,
  * the enrolment instance is enabled, and the enrolment plugin is enabled..
  *
  * @param int $competencyid The competency ID.
  * @param int $userid The user ID.
  * @return array Indexed by course ID.
  */
 public static function get_courses_with_competency_and_user($competencyid, $userid)
 {
     global $CFG, $DB;
     if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) {
         return array();
     }
     $ctxfields = \context_helper::get_preload_record_columns_sql('ctx');
     list($plugins, $params) = $DB->get_in_or_equal($plugins, SQL_PARAMS_NAMED, 'ee');
     $params['competencyid'] = $competencyid;
     $params['userid'] = $userid;
     $params['enabled'] = ENROL_INSTANCE_ENABLED;
     $params['active'] = ENROL_USER_ACTIVE;
     $params['contextlevel'] = CONTEXT_COURSE;
     // Heavily based on enrol_get_shared_courses().
     $sql = "SELECT c.*, {$ctxfields}\n                  FROM {course} c\n                  JOIN {" . static::TABLE . "} cc\n                    ON cc.courseid = c.id\n                   AND cc.competencyid = :competencyid\n                  JOIN (\n                    SELECT DISTINCT c.id\n                      FROM {enrol} e\n                      JOIN {user_enrolments} ue\n                        ON ue.enrolid = e.id\n                       AND ue.status = :active\n                       AND ue.userid = :userid\n                      JOIN {course} c\n                        ON c.id = e.courseid\n                     WHERE e.status = :enabled\n                       AND e.enrol {$plugins}\n                  ) ec ON ec.id = c.id\n             LEFT JOIN {context} ctx\n                    ON ctx.instanceid = c.id\n                   AND ctx.contextlevel = :contextlevel\n              ORDER BY c.id";
     $courses = $DB->get_records_sql($sql, $params);
     array_map('context_helper::preload_from_record', $courses);
     return $courses;
 }
예제 #5
0
 function definition()
 {
     global $CFG, $DB;
     $mform = $this->_form;
     $course = $this->_customdata;
     $this->course = $course;
     $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $course->id), '', 'customint1, id');
     // TODO: this has to be done via ajax or else it will fail very badly on large sites!
     $courses = array('' => get_string('choosedots'));
     $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
     $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
     $plugin = enrol_get_plugin('meta');
     $sortorder = 'c.' . $plugin->get_config('coursesort', 'sortorder') . ' ASC';
     $sql = "SELECT c.id, c.fullname, c.shortname, c.visible {$select} FROM {course} c {$join} ORDER BY " . $sortorder;
     $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE));
     foreach ($rs as $c) {
         if ($c->id == SITEID or $c->id == $course->id or isset($existing[$c->id])) {
             continue;
         }
         context_helper::preload_from_record($c);
         $coursecontext = context_course::instance($c->id);
         if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
             continue;
         }
         if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
             continue;
         }
         $courses[$c->id] = $coursecontext->get_context_name(false);
     }
     $rs->close();
     $mform->addElement('header', 'general', get_string('pluginname', 'enrol_meta'));
     $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_meta'), $courses);
     $mform->addRule('link', get_string('required'), 'required', null, 'client');
     $mform->addElement('hidden', 'id', null);
     $mform->setType('id', PARAM_INT);
     $this->add_action_buttons(true, get_string('addinstance', 'enrol'));
     $this->set_data(array('id' => $course->id));
 }
예제 #6
0
/**
 * Get courses tagged with a tag
 *
 * @deprecated since 3.0
 * @package  core_tag
 * @category tag
 * @param int $tagid
 * @return array of course objects
 */
function coursetag_get_tagged_courses($tagid)
{
    debugging('Function coursetag_get_tagged_courses() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
    global $DB;
    $courses = array();
    $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
    $sql = "SELECT c.*, {$ctxselect}\n            FROM {course} c\n            JOIN {tag_instance} t ON t.itemid = c.id\n            JOIN {context} ctx ON ctx.instanceid = c.id\n            WHERE t.tagid = :tagid AND\n            t.itemtype = 'course' AND\n            ctx.contextlevel = :contextlevel\n            ORDER BY c.sortorder ASC";
    $params = array('tagid' => $tagid, 'contextlevel' => CONTEXT_COURSE);
    $rs = $DB->get_recordset_sql($sql, $params);
    foreach ($rs as $course) {
        context_helper::preload_from_record($course);
        if ($course->visible == 1 || has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
            $courses[$course->id] = $course;
        }
    }
    return $courses;
}
예제 #7
0
/**
 * Returns the default courses to display on the calendar when there isn't a specific
 * course to display.
 *
 * @return array $courses Array of courses to display
 */
function calendar_get_default_courses()
{
    global $CFG, $DB;
    if (!isloggedin()) {
        return array();
    }
    $courses = array();
    if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', context_system::instance())) {
        $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
        $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
        $sql = "SELECT c.* {$select}\n                  FROM {course} c\n                  {$join}\n                  WHERE EXISTS (SELECT 1 FROM {event} e WHERE e.courseid = c.id)\n                  ";
        $courses = $DB->get_records_sql($sql, array('contextlevel' => CONTEXT_COURSE), 0, 20);
        foreach ($courses as $course) {
            context_helper::preload_from_record($course);
        }
        return $courses;
    }
    $courses = enrol_get_my_courses();
    return $courses;
}
예제 #8
0
/**
 * Preloads context information together with instances.
 * Use context_instance_preload() to strip the context info from the record and cache the context instance.
 *
 * @deprecated
 * @param string $joinon for example 'u.id'
 * @param string $contextlevel context level of instance in $joinon
 * @param string $tablealias context table alias
 * @return array with two values - select and join part
 */
function context_instance_preload_sql($joinon, $contextlevel, $tablealias)
{
    $select = ", " . context_helper::get_preload_record_columns_sql($tablealias);
    $join = "LEFT JOIN {context} {$tablealias} ON ({$tablealias}.instanceid = {$joinon} AND {$tablealias}.contextlevel = {$contextlevel})";
    return array($select, $join);
}
예제 #9
0
파일: course.php 프로젝트: rushi963/moodle
 /**
  * Set the value of this element. If values can be added or are unknown, we will
  * make sure they exist in the options array.
  * @param string|array $value The value to set.
  * @return boolean
  */
 public function setValue($value)
 {
     global $DB;
     $values = (array) $value;
     $coursestofetch = array();
     foreach ($values as $onevalue) {
         if (!$this->optionExists($onevalue) && $onevalue !== '_qf__force_multiselect_submission') {
             array_push($coursestofetch, $onevalue);
         }
     }
     if (empty($coursestofetch)) {
         return $this->setSelected(array());
     }
     // There is no API function to load a list of course from a list of ids.
     $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
     $fields = array('c.id', 'c.category', 'c.sortorder', 'c.shortname', 'c.fullname', 'c.idnumber', 'c.startdate', 'c.visible', 'c.cacherev');
     list($whereclause, $params) = $DB->get_in_or_equal($coursestofetch, SQL_PARAMS_NAMED, 'id');
     $sql = "SELECT " . join(',', $fields) . ", {$ctxselect}\n                FROM {course} c\n                JOIN {context} ctx ON c.id = ctx.instanceid AND ctx.contextlevel = :contextcourse\n                WHERE c.id " . $whereclause . " ORDER BY c.sortorder";
     $list = $DB->get_records_sql($sql, array('contextcourse' => CONTEXT_COURSE) + $params);
     $coursestoselect = array();
     foreach ($list as $course) {
         context_helper::preload_from_record($course);
         // Make sure we can see the course.
         if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
             continue;
         }
         $label = get_course_display_name_for_list($course);
         $this->addOption($label, $course->id);
         array_push($coursestoselect, $course->id);
     }
     return $this->setSelected($coursestoselect);
 }
 /**
  * Constructor.
  *
  * @param string $uniqueid Unique ID.
  * @param int $courseid Course ID.
  * @param int $groupid Group ID.
  */
 public function __construct($uniqueid, $courseid, $groupid, array $options = array(), $userid = null)
 {
     global $PAGE, $USER;
     parent::__construct($uniqueid);
     if (isset($options['rankmode'])) {
         $this->rankmode = $options['rankmode'];
     }
     if (isset($options['neighboursonly'])) {
         $this->neighboursonly = $options['neighboursonly'];
     }
     if (isset($options['neighboursabove'])) {
         $this->neighboursabove = $options['neighboursabove'];
     }
     if (isset($options['neighboursbelow'])) {
         $this->neighboursbelow = $options['neighboursbelow'];
     }
     if (isset($options['identitymode'])) {
         $this->identitymode = $options['identitymode'];
     }
     // The user ID we're viewing the ladder for.
     if ($userid === null) {
         $userid = $USER->id;
     }
     $this->userid = $userid;
     // Block XP stuff.
     $this->xpmanager = block_xp_manager::get($courseid);
     $this->xpoutput = $PAGE->get_renderer('block_xp');
     // Define columns, and headers.
     $columns = array();
     $headers = array();
     if ($this->rankmode != block_xp_manager::RANK_OFF) {
         $columns += array('rank');
         if ($this->rankmode == block_xp_manager::RANK_REL) {
             $headers += array(get_string('difference', 'block_xp'));
         } else {
             $headers += array(get_string('rank', 'block_xp'));
         }
     }
     $columns = array_merge($columns, array('userpic', 'fullname', 'lvl', 'xp', 'progress'));
     $headers = array_merge($headers, array('', get_string('fullname'), get_string('level', 'block_xp'), get_string('xp', 'block_xp'), get_string('progress', 'block_xp')));
     $this->define_columns($columns);
     $this->define_headers($headers);
     // Define SQL.
     $sqlfrom = '';
     $sqlparams = array();
     if ($groupid) {
         $sqlfrom = '{block_xp} x
                  JOIN {groups_members} gm
                    ON gm.groupid = :groupid
                   AND gm.userid = x.userid
                  JOIN {user} u
                    ON x.userid = u.id';
         $sqlparams = array('groupid' => $groupid);
     } else {
         $sqlfrom = '{block_xp} x JOIN {user} u ON x.userid = u.id';
     }
     $sqlfrom .= " JOIN {context} ctx\n                        ON ctx.instanceid = u.id\n                       AND ctx.contextlevel = :contextlevel";
     $sqlparams += array('contextlevel' => CONTEXT_USER);
     $this->sql = new stdClass();
     $this->sql->fields = 'x.*, ' . user_picture::fields('u', null, 'userid') . ', ' . context_helper::get_preload_record_columns_sql('ctx');
     $this->sql->from = $sqlfrom;
     $this->sql->where = 'courseid = :courseid';
     $this->sql->params = array_merge(array('courseid' => $courseid), $sqlparams);
     // Define various table settings.
     $this->sortable(false);
     $this->no_sorting('userpic');
     $this->no_sorting('progress');
     $this->collapsible(false);
 }
예제 #11
0
 /**
  * This function gets called by {@link settings_navigation::load_user_settings()} and actually works out
  * what can be shown/done
  *
  * @param int $courseid The current course' id
  * @param int $userid The user id to load for
  * @param string $gstitle The string to pass to get_string for the branch title
  * @return navigation_node|false
  */
 protected function generate_user_settings($courseid, $userid, $gstitle = 'usercurrentsettings')
 {
     global $DB, $CFG, $USER, $SITE;
     if ($courseid != $SITE->id) {
         if (!empty($this->page->course->id) && $this->page->course->id == $courseid) {
             $course = $this->page->course;
         } else {
             $select = context_helper::get_preload_record_columns_sql('ctx');
             $sql = "SELECT c.*, {$select}\n                          FROM {course} c\n                          JOIN {context} ctx ON c.id = ctx.instanceid\n                         WHERE c.id = :courseid AND ctx.contextlevel = :contextlevel";
             $params = array('courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
             $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
             context_helper::preload_from_record($course);
         }
     } else {
         $course = $SITE;
     }
     $coursecontext = context_course::instance($course->id);
     // Course context
     $systemcontext = context_system::instance();
     $currentuser = $USER->id == $userid;
     if ($currentuser) {
         $user = $USER;
         $usercontext = context_user::instance($user->id);
         // User context
     } else {
         $select = context_helper::get_preload_record_columns_sql('ctx');
         $sql = "SELECT u.*, {$select}\n                      FROM {user} u\n                      JOIN {context} ctx ON u.id = ctx.instanceid\n                     WHERE u.id = :userid AND ctx.contextlevel = :contextlevel";
         $params = array('userid' => $userid, 'contextlevel' => CONTEXT_USER);
         $user = $DB->get_record_sql($sql, $params, IGNORE_MISSING);
         if (!$user) {
             return false;
         }
         context_helper::preload_from_record($user);
         // Check that the user can view the profile
         $usercontext = context_user::instance($user->id);
         // User context
         $canviewuser = has_capability('moodle/user:viewdetails', $usercontext);
         if ($course->id == $SITE->id) {
             if ($CFG->forceloginforprofiles && !has_coursecontact_role($user->id) && !$canviewuser) {
                 // Reduce possibility of "browsing" userbase at site level
                 // Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
                 return false;
             }
         } else {
             $canviewusercourse = has_capability('moodle/user:viewdetails', $coursecontext);
             $userisenrolled = is_enrolled($coursecontext, $user->id, '', true);
             if (!$canviewusercourse && !$canviewuser || !$userisenrolled) {
                 return false;
             }
             $canaccessallgroups = has_capability('moodle/site:accessallgroups', $coursecontext);
             if (!$canaccessallgroups && groups_get_course_groupmode($course) == SEPARATEGROUPS && !$canviewuser) {
                 // If groups are in use, make sure we can see that group (MDL-45874). That does not apply to parents.
                 if ($courseid == $this->page->course->id) {
                     $mygroups = get_fast_modinfo($this->page->course)->groups;
                 } else {
                     $mygroups = groups_get_user_groups($courseid);
                 }
                 $usergroups = groups_get_user_groups($courseid, $userid);
                 if (!array_intersect_key($mygroups[0], $usergroups[0])) {
                     return false;
                 }
             }
         }
     }
     $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $this->page->context));
     $key = $gstitle;
     $prefurl = new moodle_url('/user/preferences.php');
     if ($gstitle != 'usercurrentsettings') {
         $key .= $userid;
         $prefurl->param('userid', $userid);
     }
     // Add a user setting branch.
     if ($gstitle == 'usercurrentsettings') {
         $dashboard = $this->add(get_string('myhome'), new moodle_url('/my/'), self::TYPE_CONTAINER, null, 'dashboard');
         // This should be set to false as we don't want to show this to the user. It's only for generating the correct
         // breadcrumb.
         $dashboard->display = false;
         if (get_home_page() == HOMEPAGE_MY) {
             $dashboard->mainnavonly = true;
         }
         $iscurrentuser = $user->id == $USER->id;
         $baseargs = array('id' => $user->id);
         if ($course->id != $SITE->id && !$iscurrentuser) {
             $baseargs['course'] = $course->id;
             $issitecourse = false;
         } else {
             // Load all categories and get the context for the system.
             $issitecourse = true;
         }
         // Add the user profile to the dashboard.
         $profilenode = $dashboard->add(get_string('profile'), new moodle_url('/user/profile.php', array('id' => $user->id)), self::TYPE_SETTING, null, 'myprofile');
         if (!empty($CFG->navadduserpostslinks)) {
             // Add nodes for forum posts and discussions if the user can view either or both
             // There are no capability checks here as the content of the page is based
             // purely on the forums the current user has access too.
             $forumtab = $profilenode->add(get_string('forumposts', 'forum'));
             $forumtab->add(get_string('posts', 'forum'), new moodle_url('/mod/forum/user.php', $baseargs), null, 'myposts');
             $forumtab->add(get_string('discussions', 'forum'), new moodle_url('/mod/forum/user.php', array_merge($baseargs, array('mode' => 'discussions'))), null, 'mydiscussions');
         }
         // Add blog nodes.
         if (!empty($CFG->enableblogs)) {
             if (!$this->cache->cached('userblogoptions' . $user->id)) {
                 require_once $CFG->dirroot . '/blog/lib.php';
                 // Get all options for the user.
                 $options = blog_get_options_for_user($user);
                 $this->cache->set('userblogoptions' . $user->id, $options);
             } else {
                 $options = $this->cache->{'userblogoptions' . $user->id};
             }
             if (count($options) > 0) {
                 $blogs = $profilenode->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER);
                 foreach ($options as $type => $option) {
                     if ($type == "rss") {
                         $blogs->add($option['string'], $option['link'], self::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
                     } else {
                         $blogs->add($option['string'], $option['link'], self::TYPE_SETTING, null, 'blog' . $type);
                     }
                 }
             }
         }
         // Add the messages link.
         // It is context based so can appear in the user's profile and in course participants information.
         if (!empty($CFG->messaging)) {
             $messageargs = array('user1' => $USER->id);
             if ($USER->id != $user->id) {
                 $messageargs['user2'] = $user->id;
             }
             if ($course->id != $SITE->id) {
                 $messageargs['viewing'] = MESSAGE_VIEW_COURSE . $course->id;
             }
             $url = new moodle_url('/message/index.php', $messageargs);
             $dashboard->add(get_string('messages', 'message'), $url, self::TYPE_SETTING, null, 'messages');
         }
         // Add the "My private files" link.
         // This link doesn't have a unique display for course context so only display it under the user's profile.
         if ($issitecourse && $iscurrentuser && has_capability('moodle/user:manageownfiles', $usercontext)) {
             $url = new moodle_url('/user/files.php');
             $dashboard->add(get_string('privatefiles'), $url, self::TYPE_SETTING);
         }
         // Add a node to view the users notes if permitted.
         if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $coursecontext)) {
             $url = new moodle_url('/notes/index.php', array('user' => $user->id));
             if ($coursecontext->instanceid != SITEID) {
                 $url->param('course', $coursecontext->instanceid);
             }
             $profilenode->add(get_string('notes', 'notes'), $url);
         }
         // Show the grades node.
         if ($issitecourse && $iscurrentuser || has_capability('moodle/user:viewdetails', $usercontext)) {
             require_once $CFG->dirroot . '/user/lib.php';
             // Set the grades node to link to the "Grades" page.
             if ($course->id == SITEID) {
                 $url = user_mygrades_url($user->id, $course->id);
             } else {
                 // Otherwise we are in a course and should redirect to the user grade report (Activity report version).
                 $url = new moodle_url('/course/user.php', array('mode' => 'grade', 'id' => $course->id, 'user' => $user->id));
             }
             $dashboard->add(get_string('grades', 'grades'), $url, self::TYPE_SETTING, null, 'mygrades');
         }
         // Let plugins hook into user navigation.
         $pluginsfunction = get_plugins_with_function('extend_navigation_user', 'lib.php');
         foreach ($pluginsfunction as $plugintype => $plugins) {
             if ($plugintype != 'report') {
                 foreach ($plugins as $pluginfunction) {
                     $pluginfunction($profilenode, $user, $usercontext, $course, $coursecontext);
                 }
             }
         }
         $usersetting = navigation_node::create(get_string('preferences', 'moodle'), $prefurl, self::TYPE_CONTAINER, null, $key);
         $dashboard->add_node($usersetting);
     } else {
         $usersetting = $this->add(get_string('preferences', 'moodle'), $prefurl, self::TYPE_CONTAINER, null, $key);
         $usersetting->display = false;
     }
     $usersetting->id = 'usersettings';
     // Check if the user has been deleted.
     if ($user->deleted) {
         if (!has_capability('moodle/user:update', $coursecontext)) {
             // We can't edit the user so just show the user deleted message.
             $usersetting->add(get_string('userdeleted'), null, self::TYPE_SETTING);
         } else {
             // We can edit the user so show the user deleted message and link it to the profile.
             if ($course->id == $SITE->id) {
                 $profileurl = new moodle_url('/user/profile.php', array('id' => $user->id));
             } else {
                 $profileurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
             }
             $usersetting->add(get_string('userdeleted'), $profileurl, self::TYPE_SETTING);
         }
         return true;
     }
     $userauthplugin = false;
     if (!empty($user->auth)) {
         $userauthplugin = get_auth_plugin($user->auth);
     }
     $useraccount = $usersetting->add(get_string('useraccount'), null, self::TYPE_CONTAINER, null, 'useraccount');
     // Add the profile edit link.
     if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
         if (($currentuser || is_siteadmin($USER) || !is_siteadmin($user)) && has_capability('moodle/user:update', $systemcontext)) {
             $url = new moodle_url('/user/editadvanced.php', array('id' => $user->id, 'course' => $course->id));
             $useraccount->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
         } else {
             if (has_capability('moodle/user:editprofile', $usercontext) && !is_siteadmin($user) || $currentuser && has_capability('moodle/user:editownprofile', $systemcontext)) {
                 if ($userauthplugin && $userauthplugin->can_edit_profile()) {
                     $url = $userauthplugin->edit_profile_url();
                     if (empty($url)) {
                         $url = new moodle_url('/user/edit.php', array('id' => $user->id, 'course' => $course->id));
                     }
                     $useraccount->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
                 }
             }
         }
     }
     // Change password link.
     if ($userauthplugin && $currentuser && !\core\session\manager::is_loggedinas() && !isguestuser() && has_capability('moodle/user:changeownpassword', $systemcontext) && $userauthplugin->can_change_password()) {
         $passwordchangeurl = $userauthplugin->change_password_url();
         if (empty($passwordchangeurl)) {
             $passwordchangeurl = new moodle_url('/login/change_password.php', array('id' => $course->id));
         }
         $useraccount->add(get_string("changepassword"), $passwordchangeurl, self::TYPE_SETTING, null, 'changepassword');
     }
     if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
         if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) {
             $url = new moodle_url('/user/language.php', array('id' => $user->id, 'course' => $course->id));
             $useraccount->add(get_string('preferredlanguage'), $url, self::TYPE_SETTING, null, 'preferredlanguage');
         }
     }
     $pluginmanager = core_plugin_manager::instance();
     $enabled = $pluginmanager->get_enabled_plugins('mod');
     if (isset($enabled['forum']) && isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
         if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) {
             $url = new moodle_url('/user/forum.php', array('id' => $user->id, 'course' => $course->id));
             $useraccount->add(get_string('forumpreferences'), $url, self::TYPE_SETTING);
         }
     }
     $editors = editors_get_enabled();
     if (count($editors) > 1) {
         if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
             if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) {
                 $url = new moodle_url('/user/editor.php', array('id' => $user->id, 'course' => $course->id));
                 $useraccount->add(get_string('editorpreferences'), $url, self::TYPE_SETTING);
             }
         }
     }
     // Add "Course preferences" link.
     if (isloggedin() && !isguestuser($user)) {
         if ($currentuser && has_capability('moodle/user:editownprofile', $systemcontext) || has_capability('moodle/user:editprofile', $usercontext)) {
             $url = new moodle_url('/user/course.php', array('id' => $user->id, 'course' => $course->id));
             $useraccount->add(get_string('coursepreferences'), $url, self::TYPE_SETTING, null, 'coursepreferences');
         }
     }
     // View the roles settings.
     if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage'), $usercontext)) {
         $roles = $usersetting->add(get_string('roles'), null, self::TYPE_SETTING);
         $url = new moodle_url('/admin/roles/usersroles.php', array('userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('thisusersroles', 'role'), $url, self::TYPE_SETTING);
         $assignableroles = get_assignable_roles($usercontext, ROLENAME_BOTH);
         if (!empty($assignableroles)) {
             $url = new moodle_url('/admin/roles/assign.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('assignrolesrelativetothisuser', 'role'), $url, self::TYPE_SETTING);
         }
         if (has_capability('moodle/role:review', $usercontext) || count(get_overridable_roles($usercontext, ROLENAME_BOTH)) > 0) {
             $url = new moodle_url('/admin/roles/permissions.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('permissions', 'role'), $url, self::TYPE_SETTING);
         }
         $url = new moodle_url('/admin/roles/check.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING);
     }
     // Repositories.
     if (!$this->cache->cached('contexthasrepos' . $usercontext->id)) {
         require_once $CFG->dirroot . '/repository/lib.php';
         $editabletypes = repository::get_editable_types($usercontext);
         $haseditabletypes = !empty($editabletypes);
         unset($editabletypes);
         $this->cache->set('contexthasrepos' . $usercontext->id, $haseditabletypes);
     } else {
         $haseditabletypes = $this->cache->{'contexthasrepos' . $usercontext->id};
     }
     if ($haseditabletypes) {
         $repositories = $usersetting->add(get_string('repositories', 'repository'), null, self::TYPE_SETTING);
         $repositories->add(get_string('manageinstances', 'repository'), new moodle_url('/repository/manage_instances.php', array('contextid' => $usercontext->id)));
     }
     // Portfolio.
     if ($currentuser && !empty($CFG->enableportfolios) && has_capability('moodle/portfolio:export', $systemcontext)) {
         require_once $CFG->libdir . '/portfoliolib.php';
         if (portfolio_has_visible_instances()) {
             $portfolio = $usersetting->add(get_string('portfolios', 'portfolio'), null, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfolio.php', array('courseid' => $course->id));
             $portfolio->add(get_string('configure', 'portfolio'), $url, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfoliologs.php', array('courseid' => $course->id));
             $portfolio->add(get_string('logs', 'portfolio'), $url, self::TYPE_SETTING);
         }
     }
     $enablemanagetokens = false;
     if (!empty($CFG->enablerssfeeds)) {
         $enablemanagetokens = true;
     } else {
         if (!is_siteadmin($USER->id) && !empty($CFG->enablewebservices) && has_capability('moodle/webservice:createtoken', context_system::instance())) {
             $enablemanagetokens = true;
         }
     }
     // Security keys.
     if ($currentuser && $enablemanagetokens) {
         $url = new moodle_url('/user/managetoken.php', array('sesskey' => sesskey()));
         $useraccount->add(get_string('securitykeys', 'webservice'), $url, self::TYPE_SETTING);
     }
     // Messaging.
     if ($currentuser && has_capability('moodle/user:editownmessageprofile', $systemcontext) || !isguestuser($user) && has_capability('moodle/user:editmessageprofile', $usercontext) && !is_primary_admin($user->id)) {
         $url = new moodle_url('/message/edit.php', array('id' => $user->id));
         $useraccount->add(get_string('messaging', 'message'), $url, self::TYPE_SETTING);
     }
     // Blogs.
     if ($currentuser && !empty($CFG->enableblogs)) {
         $blog = $usersetting->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER, null, 'blogs');
         if (has_capability('moodle/blog:view', $systemcontext)) {
             $blog->add(get_string('preferences', 'blog'), new moodle_url('/blog/preferences.php'), navigation_node::TYPE_SETTING);
         }
         if (!empty($CFG->useexternalblogs) && $CFG->maxexternalblogsperuser > 0 && has_capability('moodle/blog:manageexternal', $systemcontext)) {
             $blog->add(get_string('externalblogs', 'blog'), new moodle_url('/blog/external_blogs.php'), navigation_node::TYPE_SETTING);
             $blog->add(get_string('addnewexternalblog', 'blog'), new moodle_url('/blog/external_blog_edit.php'), navigation_node::TYPE_SETTING);
         }
         // Remove the blog node if empty.
         $blog->trim_if_empty();
     }
     // Badges.
     if ($currentuser && !empty($CFG->enablebadges)) {
         $badges = $usersetting->add(get_string('badges'), null, navigation_node::TYPE_CONTAINER, null, 'badges');
         if (has_capability('moodle/badges:manageownbadges', $usercontext)) {
             $url = new moodle_url('/badges/mybadges.php');
             $badges->add(get_string('managebadges', 'badges'), $url, self::TYPE_SETTING);
         }
         $badges->add(get_string('preferences', 'badges'), new moodle_url('/badges/preferences.php'), navigation_node::TYPE_SETTING);
         if (!empty($CFG->badges_allowexternalbackpack)) {
             $badges->add(get_string('backpackdetails', 'badges'), new moodle_url('/badges/mybackpack.php'), navigation_node::TYPE_SETTING);
         }
     }
     // Let plugins hook into user settings navigation.
     $pluginsfunction = get_plugins_with_function('extend_navigation_user_settings', 'lib.php');
     foreach ($pluginsfunction as $plugintype => $plugins) {
         foreach ($plugins as $pluginfunction) {
             $pluginfunction($usersetting, $user, $usercontext, $course, $coursecontext);
         }
     }
     return $usersetting;
 }
예제 #12
0
 /**
  * This method actually loads the blocks for our page from the database.
  *
  * @param boolean|null $includeinvisible
  *      null (default) - load hidden blocks if $this->page->user_is_editing();
  *      true - load hidden blocks.
  *      false - don't load hidden blocks.
  */
 public function load_blocks($includeinvisible = null)
 {
     global $DB, $CFG;
     if (!is_null($this->birecordsbyregion)) {
         // Already done.
         return;
     }
     if ($CFG->version < 2009050619) {
         // Upgrade/install not complete. Don't try too show any blocks.
         $this->birecordsbyregion = array();
         return;
     }
     // Ensure we have been initialised.
     if (is_null($this->defaultregion)) {
         $this->page->initialise_theme_and_output();
         // If there are still no block regions, then there are no blocks on this page.
         if (empty($this->regions)) {
             $this->birecordsbyregion = array();
             return;
         }
     }
     // Check if we need to load normal blocks
     if ($this->fakeblocksonly) {
         $this->birecordsbyregion = $this->prepare_per_region_arrays();
         return;
     }
     if (is_null($includeinvisible)) {
         $includeinvisible = $this->page->user_is_editing();
     }
     if ($includeinvisible) {
         $visiblecheck = '';
     } else {
         $visiblecheck = 'AND (bp.visible = 1 OR bp.visible IS NULL)';
     }
     $context = $this->page->context;
     $contexttest = 'bi.parentcontextid IN (:contextid2, :contextid3)';
     $parentcontextparams = array();
     $parentcontextids = $context->get_parent_context_ids();
     if ($parentcontextids) {
         list($parentcontexttest, $parentcontextparams) = $DB->get_in_or_equal($parentcontextids, SQL_PARAMS_NAMED, 'parentcontext');
         $contexttest = "({$contexttest} OR (bi.showinsubcontexts = 1 AND bi.parentcontextid {$parentcontexttest}))";
     }
     $pagetypepatterns = matching_page_type_patterns($this->page->pagetype);
     list($pagetypepatterntest, $pagetypepatternparams) = $DB->get_in_or_equal($pagetypepatterns, SQL_PARAMS_NAMED, 'pagetypepatterntest');
     $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
     $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = bi.id AND ctx.contextlevel = :contextlevel)";
     $systemcontext = context_system::instance();
     $params = array('contextlevel' => CONTEXT_BLOCK, 'subpage1' => $this->page->subpage, 'subpage2' => $this->page->subpage, 'contextid1' => $context->id, 'contextid2' => $context->id, 'contextid3' => $systemcontext->id, 'pagetype' => $this->page->pagetype);
     if ($this->page->subpage === '') {
         $params['subpage1'] = '';
         $params['subpage2'] = '';
     }
     $sql = "SELECT\n                    bi.id,\n                    bp.id AS blockpositionid,\n                    bi.blockname,\n                    bi.parentcontextid,\n                    bi.showinsubcontexts,\n                    bi.pagetypepattern,\n                    bi.subpagepattern,\n                    bi.defaultregion,\n                    bi.defaultweight,\n                    COALESCE(bp.visible, 1) AS visible,\n                    COALESCE(bp.region, bi.defaultregion) AS region,\n                    COALESCE(bp.weight, bi.defaultweight) AS weight,\n                    bi.configdata\n                    {$ccselect}\n\n                FROM {block_instances} bi\n                JOIN {block} b ON bi.blockname = b.name\n                LEFT JOIN {block_positions} bp ON bp.blockinstanceid = bi.id\n                                                  AND bp.contextid = :contextid1\n                                                  AND bp.pagetype = :pagetype\n                                                  AND bp.subpage = :subpage1\n                {$ccjoin}\n\n                WHERE\n                {$contexttest}\n                AND bi.pagetypepattern {$pagetypepatterntest}\n                AND (bi.subpagepattern IS NULL OR bi.subpagepattern = :subpage2)\n                {$visiblecheck}\n                AND b.visible = 1\n\n                ORDER BY\n                    COALESCE(bp.region, bi.defaultregion),\n                    COALESCE(bp.weight, bi.defaultweight),\n                    bi.id";
     $blockinstances = $DB->get_recordset_sql($sql, $params + $parentcontextparams + $pagetypepatternparams);
     $this->birecordsbyregion = $this->prepare_per_region_arrays();
     $unknown = array();
     foreach ($blockinstances as $bi) {
         context_helper::preload_from_record($bi);
         if ($this->is_known_region($bi->region)) {
             $this->birecordsbyregion[$bi->region][] = $bi;
         } else {
             $unknown[] = $bi;
         }
     }
     // Pages don't necessarily have a defaultregion. The  one time this can
     // happen is when there are no theme block regions, but the script itself
     // has a block region in the main content area.
     if (!empty($this->defaultregion)) {
         $this->birecordsbyregion[$this->defaultregion] = array_merge($this->birecordsbyregion[$this->defaultregion], $unknown);
     }
 }
예제 #13
0
파일: lib.php 프로젝트: abhilash1994/moodle
/**
 * Gets all of the courses where the provided user has posted in a forum.
 *
 * @global moodle_database $DB The database connection
 * @param stdClass $user The user who's posts we are looking for
 * @param bool $discussionsonly If true only look for discussions started by the user
 * @param bool $includecontexts If set to trye contexts for the courses will be preloaded
 * @param int $limitfrom The offset of records to return
 * @param int $limitnum The number of records to return
 * @return array An array of courses
 */
function forum_get_courses_user_posted_in($user, $discussionsonly = false, $includecontexts = true, $limitfrom = null, $limitnum = null)
{
    global $DB;
    // If we are only after discussions we need only look at the forum_discussions
    // table and join to the userid there. If we are looking for posts then we need
    // to join to the forum_posts table.
    if (!$discussionsonly) {
        $subquery = "(SELECT DISTINCT fd.course\n                         FROM {forum_discussions} fd\n                         JOIN {forum_posts} fp ON fp.discussion = fd.id\n                        WHERE fp.userid = :userid )";
    } else {
        $subquery = "(SELECT DISTINCT fd.course\n                         FROM {forum_discussions} fd\n                        WHERE fd.userid = :userid )";
    }
    $params = array('userid' => $user->id);
    // Join to the context table so that we can preload contexts if required.
    if ($includecontexts) {
        $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
        $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
        $params['contextlevel'] = CONTEXT_COURSE;
    } else {
        $ctxselect = '';
        $ctxjoin = '';
    }
    // Now we need to get all of the courses to search.
    // All courses where the user has posted within a forum will be returned.
    $sql = "SELECT c.* {$ctxselect}\n            FROM {course} c\n            {$ctxjoin}\n            WHERE c.id IN ({$subquery})";
    $courses = $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
    if ($includecontexts) {
        array_map('context_helper::preload_from_record', $courses);
    }
    return $courses;
}
 /**
      * Helper function to create list of user fullnames shown in log report.
      *
      * This will update $this->userfullnames array with userfullname,
      * which will be used to render logs in table.
      *
      * @since   Moodle 2.9
      * @return  void
 
     protected function update_users_used() {
         global $DB;
    $this->userfullnames = array();
         $userids = array();
    // For each event cache full username.
         // Get list of userids which will be shown in log report.
         foreach ($this->rawdata as $event) {
             $logextra = $event->get_logextra();
             if (!empty($event->userid) && empty($userids[$event->userid])) {
                 $userids[$event->userid] = $event->userid;
             }
             if (!empty($logextra['realuserid']) && empty($userids[$logextra['realuserid']])) {
                 $userids[$logextra['realuserid']] = $logextra['realuserid'];
             }
             if (!empty($event->relateduserid) && empty($userids[$event->relateduserid])) {
                 $userids[$event->relateduserid] = $event->relateduserid;
             }
         }
         // Get user fullname and put that in return list.
         if (!empty($userids)) {
             list($usql, $uparams) = $DB->get_in_or_equal($userids);
             $users = $DB->get_records_sql("SELECT id," . get_all_user_name_fields(true) . " FROM {user} WHERE id " . $usql,
                     $uparams);
             foreach ($users as $userid => $user) {
                 $this->userfullnames[$userid] = fullname($user);
                 unset($userids[$userid]);
             }
        // We fill the array with false values for the users that don't exist anymore
             // in the database so we don't need to query the db again later.
             foreach ($userids as $userid) {
                 $this->userfullnames[$userid] = false;
             }
         }
     }
 */
 protected function update_users_used()
 {
     global $SITE, $DB;
     $this->userfullnames = array();
     $this->courseshortnames = array($SITE->id => $SITE->shortname);
     $userids = array();
     $courseids = array();
     // For each event cache full username and course.
     // Get list of userids and courseids which will be shown in log report.
     foreach ($this->rawdata as $event) {
         $logextra = $event->get_logextra();
         if (!empty($event->userid) && empty($userids[$event->userid])) {
             $userids[$event->userid] = $event->userid;
         }
         if (!empty($logextra['realuserid']) && empty($userids[$logextra['realuserid']])) {
             $userids[$logextra['realuserid']] = $logextra['realuserid'];
         }
         if (!empty($event->relateduserid) && empty($userids[$event->relateduserid])) {
             $userids[$event->relateduserid] = $event->relateduserid;
         }
         if (!empty($event->courseid) && $event->courseid != $SITE->id && !in_array($event->courseid, $courseids)) {
             $courseids[] = $event->courseid;
         }
     }
     // Closing it just in case, we can not rewind moodle recordsets anyway.
     if ($this->rawdata instanceof \core\dml\recordset_walk || $this->rawdata instanceof moodle_recordset) {
         $this->rawdata->close();
     }
     // Get user fullname and put that in return list.
     if (!empty($userids)) {
         list($usql, $uparams) = $DB->get_in_or_equal($userids);
         $users = $DB->get_records_sql("SELECT id," . get_all_user_name_fields(true) . " FROM {user} WHERE id " . $usql, $uparams);
         foreach ($users as $userid => $user) {
             $this->userfullnames[$userid] = fullname($user);
             unset($userids[$userid]);
         }
         // We fill the array with false values for the users that don't exist anymore
         // in the database so we don't need to query the db again later.
         foreach ($userids as $userid) {
             $this->userfullnames[$userid] = false;
         }
     }
     // Get course shortname and put that in return list.
     if (!empty($courseids)) {
         // If all logs don't belong to site level then get course info.
         list($coursesql, $courseparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
         $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
         $courseparams['contextlevel'] = CONTEXT_COURSE;
         $sql = "\n                SELECT\n                    c.id, c.shortname {$ccselect}\n                FROM\n                    {course} c\n                LEFT JOIN\n                    {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)\n                WHERE\n                    c.id " . $coursesql;
         // A response code other than 0 is a failure
         $courses = $DB->get_records_sql($sql, $courseparams);
         foreach ($courses as $courseid => $course) {
             $url = new moodle_url("/course/view.php", array('id' => $courseid));
             context_helper::preload_from_record($course);
             $context = context_course::instance($courseid, IGNORE_MISSING);
             // Method format_string() takes care of missing contexts.
             $this->courseshortnames[$courseid] = html_writer::link($url, format_string($course->shortname, true, array('context' => $context)));
         }
     }
 }
예제 #15
0
파일: datalib.php 프로젝트: evltuma/moodle
/**
 * A list of courses that match a search
 *
 * @global object
 * @global object
 * @param array $searchterms An array of search criteria
 * @param string $sort A field and direction to sort by
 * @param int $page The page number to get
 * @param int $recordsperpage The number of records per page
 * @param int $totalcount Passed in by reference.
 * @param array $requiredcapabilities Extra list of capabilities used to filter courses
 * @return object {@link $COURSE} records
 */
function get_courses_search($searchterms, $sort, $page, $recordsperpage, &$totalcount, $requiredcapabilities = array())
{
    global $CFG, $DB;
    if ($DB->sql_regex_supported()) {
        $REGEXP = $DB->sql_regex(true);
        $NOTREGEXP = $DB->sql_regex(false);
    }
    $searchcond = array();
    $params = array();
    $i = 0;
    // Thanks Oracle for your non-ansi concat and type limits in coalesce. MDL-29912
    if ($DB->get_dbfamily() == 'oracle') {
        $concat = "(c.summary|| ' ' || c.fullname || ' ' || c.idnumber || ' ' || c.shortname)";
    } else {
        $concat = $DB->sql_concat("COALESCE(c.summary, '')", "' '", 'c.fullname', "' '", 'c.idnumber', "' '", 'c.shortname');
    }
    foreach ($searchterms as $searchterm) {
        $i++;
        $NOT = false;
        /// Initially we aren't going to perform NOT LIKE searches, only MSSQL and Oracle
        /// will use it to simulate the "-" operator with LIKE clause
        /// Under Oracle and MSSQL, trim the + and - operators and perform
        /// simpler LIKE (or NOT LIKE) queries
        if (!$DB->sql_regex_supported()) {
            if (substr($searchterm, 0, 1) == '-') {
                $NOT = true;
            }
            $searchterm = trim($searchterm, '+-');
        }
        // TODO: +- may not work for non latin languages
        if (substr($searchterm, 0, 1) == '+') {
            $searchterm = trim($searchterm, '+-');
            $searchterm = preg_quote($searchterm, '|');
            $searchcond[] = "{$concat} {$REGEXP} :ss{$i}";
            $params['ss' . $i] = "(^|[^a-zA-Z0-9]){$searchterm}([^a-zA-Z0-9]|\$)";
        } else {
            if (substr($searchterm, 0, 1) == "-") {
                $searchterm = trim($searchterm, '+-');
                $searchterm = preg_quote($searchterm, '|');
                $searchcond[] = "{$concat} {$NOTREGEXP} :ss{$i}";
                $params['ss' . $i] = "(^|[^a-zA-Z0-9]){$searchterm}([^a-zA-Z0-9]|\$)";
            } else {
                $searchcond[] = $DB->sql_like($concat, ":ss{$i}", false, true, $NOT);
                $params['ss' . $i] = "%{$searchterm}%";
            }
        }
    }
    if (empty($searchcond)) {
        $searchcond = array('1 = 1');
    }
    $searchcond = implode(" AND ", $searchcond);
    $courses = array();
    $c = 0;
    // counts how many visible courses we've seen
    // Tiki pagination
    $limitfrom = $page * $recordsperpage;
    $limitto = $limitfrom + $recordsperpage;
    $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
    $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
    $params['contextlevel'] = CONTEXT_COURSE;
    $sql = "SELECT c.* {$ccselect}\n              FROM {course} c\n           {$ccjoin}\n             WHERE {$searchcond} AND c.id <> " . SITEID . "\n          ORDER BY {$sort}";
    $rs = $DB->get_recordset_sql($sql, $params);
    foreach ($rs as $course) {
        // Preload contexts only for hidden courses or courses we need to return.
        context_helper::preload_from_record($course);
        $coursecontext = context_course::instance($course->id);
        if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
            continue;
        }
        if (!empty($requiredcapabilities)) {
            if (!has_all_capabilities($requiredcapabilities, $coursecontext)) {
                continue;
            }
        }
        // Don't exit this loop till the end
        // we need to count all the visible courses
        // to update $totalcount
        if ($c >= $limitfrom && $c < $limitto) {
            $courses[$course->id] = $course;
        }
        $c++;
    }
    $rs->close();
    // our caller expects 2 bits of data - our return
    // array, and an updated $totalcount
    $totalcount = $c;
    return $courses;
}
예제 #16
0
 /**
  * Returns an array of grades calculated by aggregating item ratings.
  *
  * @param stdClass $options {
  *            userid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
  *            aggregationmethod => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
  *            scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
  *            itemtable => int the table containing the items [required]
  *            itemtableusercolum => int the column of the user table containing the item owner's user id [required]
  *            component => The component for the ratings [required]
  *            ratingarea => The ratingarea for the ratings [required]
  *            contextid => int the context in which the rated items exist [optional]
  *            modulename => string the name of the module [optional]
  *            moduleid => int the id of the module instance [optional]
  * }
  * @return array the array of the user's grades
  */
 public function get_user_grades($options)
 {
     global $DB;
     $contextid = null;
     if (!isset($options->component)) {
         throw new coding_exception('The component option is now a required option when getting user grades from ratings.');
     }
     if (!isset($options->ratingarea)) {
         throw new coding_exception('The ratingarea option is now a required option when getting user grades from ratings.');
     }
     //if the calling code doesn't supply a context id we'll have to figure it out
     if (!empty($options->contextid)) {
         $contextid = $options->contextid;
     } else {
         if (!empty($options->cmid)) {
             //not implemented as not currently used although cmid is potentially available (the forum supplies it)
             //Is there a convenient way to get a context id from a cm id?
             //$cmidnumber = $options->cmidnumber;
         } else {
             if (!empty($options->modulename) && !empty($options->moduleid)) {
                 $modulename = $options->modulename;
                 $moduleid = intval($options->moduleid);
                 // Going direct to the db for the context id seems wrong.
                 $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
                 $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = cm.id AND ctx.contextlevel = :contextlevel)";
                 $sql = "SELECT cm.* {$ctxselect}\n                      FROM {course_modules} cm\n                 LEFT JOIN {modules} mo ON mo.id = cm.module\n                 LEFT JOIN {{$modulename}} m ON m.id = cm.instance {$ctxjoin}\n                     WHERE mo.name=:modulename AND\n                           m.id=:moduleid";
                 $params = array('modulename' => $modulename, 'moduleid' => $moduleid, 'contextlevel' => CONTEXT_MODULE);
                 $contextrecord = $DB->get_record_sql($sql, $params, '*', MUST_EXIST);
                 $contextid = $contextrecord->ctxid;
             }
         }
     }
     $params = array();
     $params['contextid'] = $contextid;
     $params['component'] = $options->component;
     $params['ratingarea'] = $options->ratingarea;
     $itemtable = $options->itemtable;
     $itemtableusercolumn = $options->itemtableusercolumn;
     $scaleid = $options->scaleid;
     $aggregationstring = $this->get_aggregation_method($options->aggregationmethod);
     //if userid is not 0 we only want the grade for a single user
     $singleuserwhere = '';
     if ($options->userid != 0) {
         $params['userid1'] = intval($options->userid);
         $singleuserwhere = "AND i.{$itemtableusercolumn} = :userid1";
     }
     //MDL-24648 The where line used to be "WHERE (r.contextid is null or r.contextid=:contextid)"
     //r.contextid will be null for users who haven't been rated yet
     //no longer including users who haven't been rated to reduce memory requirements
     $sql = "SELECT u.id as id, u.id AS userid, {$aggregationstring}(r.rating) AS rawgrade\n                  FROM {user} u\n             LEFT JOIN {{$itemtable}} i ON u.id=i.{$itemtableusercolumn}\n             LEFT JOIN {rating} r ON r.itemid=i.id\n                 WHERE r.contextid = :contextid AND\n                       r.component = :component AND\n                       r.ratingarea = :ratingarea\n                       {$singleuserwhere}\n              GROUP BY u.id";
     $results = $DB->get_records_sql($sql, $params);
     if ($results) {
         $scale = null;
         $max = 0;
         if ($options->scaleid >= 0) {
             //numeric
             $max = $options->scaleid;
         } else {
             //custom scales
             $scale = $DB->get_record('scale', array('id' => -$options->scaleid));
             if ($scale) {
                 $scale = explode(',', $scale->scale);
                 $max = count($scale);
             } else {
                 debugging('rating_manager::get_user_grades() received a scale ID that doesnt exist');
             }
         }
         // it could throw off the grading if count and sum returned a rawgrade higher than scale
         // so to prevent it we review the results and ensure that rawgrade does not exceed the scale, if it does we set rawgrade = scale (i.e. full credit)
         foreach ($results as $rid => $result) {
             if ($options->scaleid >= 0) {
                 //numeric
                 if ($result->rawgrade > $options->scaleid) {
                     $results[$rid]->rawgrade = $options->scaleid;
                 }
             } else {
                 //scales
                 if (!empty($scale) && $result->rawgrade > $max) {
                     $results[$rid]->rawgrade = $max;
                 }
             }
         }
     }
     return $results;
 }
예제 #17
0
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require '../../config.php';
require_once "{$CFG->dirroot}/enrol/locallib.php";
require_once "{$CFG->dirroot}/enrol/renderer.php";
$ueid = required_param('ue', PARAM_INT);
// user enrolment id
$filter = optional_param('ifilter', 0, PARAM_INT);
$confirm = optional_param('confirm', false, PARAM_BOOL);
// Get the user enrolment object
$ue = $DB->get_record('user_enrolments', array('id' => $ueid), '*', MUST_EXIST);
// Get the user for whom the enrolment is
$user = $DB->get_record('user', array('id' => $ue->userid), '*', MUST_EXIST);
// Get the course the enrolment is to
//list($ctxsql, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
$ctxsql = context_helper::get_preload_record_columns_sql('ctx');
$sql = "SELECT c.*, {$ctxsql}\n          FROM {course} c\n     LEFT JOIN {enrol} e ON e.courseid = c.id\n\t\t LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextcourse)\n         WHERE e.id = :enrolid";
$params = array('enrolid' => $ue->enrolid, 'contextcourse' => CONTEXT_COURSE);
$course = $DB->get_record_sql($sql, $params, MUST_EXIST);
context_helper::preload_from_record($course);
// Make sure it's not the front page
if ($course->id == SITEID) {
    redirect(new moodle_url('/'));
}
// Obviously
require_login($course);
// Make sure the user can unenrol users.
require_capability("enrol/apply:unenrol", context_course::instance($course->id));
// Get the enrolment manager for this course
$manager = new course_enrolment_manager($PAGE, $course, $filter);
// Get an enrolment users table object. Doign this will automatically retrieve the the URL params
예제 #18
0
파일: functions.php 프로젝트: dariogs/moosh
function get_all_courses($sort = "c.sortorder DESC", $fields = "c.*")
{
    global $CFG, $DB;
    require_once $CFG->dirroot . '/lib/accesslib.php';
    $where = 'WHERE c.id != 1';
    if (empty($sort)) {
        $sortstatement = "";
    } else {
        $sortstatement = "ORDER BY {$sort}";
    }
    $ccselect = ", " . context_helper::get_preload_record_columns_sql('ctx');
    $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
    $sql = "SELECT {$fields} {$ccselect}\n                FROM {course} c\n                {$ccjoin}\n                {$where}\n                {$sortstatement}";
    $param = array('contextlevel' => CONTEXT_COURSE);
    return $DB->get_records_sql($sql, $param);
}
 /**
  * Resort the courses within this category by the given field.
  *
  * @param string $field One of fullname, shortname, idnumber or descending values of each (appended desc)
  * @param bool $cleanup
  * @return bool True for success.
  * @throws coding_exception
  */
 public function resort_courses($field, $cleanup = true)
 {
     global $DB;
     $desc = false;
     if (substr($field, -4) === "desc") {
         $desc = true;
         $field = substr($field, 0, -4);
         // Remove "desc" from field name.
     }
     if ($field !== 'fullname' && $field !== 'shortname' && $field !== 'idnumber' && $field !== 'timecreated') {
         // This is ultra important as we use $field in an SQL statement below this.
         throw new coding_exception('Invalid field requested');
     }
     $ctxfields = context_helper::get_preload_record_columns_sql('ctx');
     $sql = "SELECT c.id, c.sortorder, c.{$field}, {$ctxfields}\n                  FROM {course} c\n             LEFT JOIN {context} ctx ON ctx.instanceid = c.id\n                 WHERE ctx.contextlevel = :ctxlevel AND\n                       c.category = :categoryid";
     $params = array('ctxlevel' => CONTEXT_COURSE, 'categoryid' => $this->id);
     $courses = $DB->get_records_sql($sql, $params);
     if (count($courses) > 0) {
         foreach ($courses as $courseid => $course) {
             context_helper::preload_from_record($course);
             if ($field === 'idnumber') {
                 $course->sortby = $course->idnumber;
             } else {
                 // It'll require formatting.
                 $options = array('context' => context_course::instance($course->id));
                 // We format the string first so that it appears as the user would see it.
                 // This ensures the sorting makes sense to them. However it won't necessarily make
                 // sense to everyone if things like multilang filters are enabled.
                 // We then strip any tags as we don't want things such as image tags skewing the
                 // sort results.
                 $course->sortby = strip_tags(format_string($course->{$field}, true, $options));
             }
             // We set it back here rather than using references as there is a bug with using
             // references in a foreach before passing as an arg by reference.
             $courses[$courseid] = $course;
         }
         // Sort the courses.
         core_collator::asort_objects_by_property($courses, 'sortby', core_collator::SORT_NATURAL);
         if (!empty($desc)) {
             $courses = array_reverse($courses);
         }
         $i = 1;
         foreach ($courses as $course) {
             $DB->set_field('course', 'sortorder', $this->sortorder + $i, array('id' => $course->id));
             $i++;
         }
         if ($cleanup) {
             // This should not be needed but we do it just to be safe.
             fix_course_sortorder();
             cache_helper::purge_by_event('changesincourse');
         }
     }
     return true;
 }
예제 #20
0
 /**
  * This function returns a nice list representing category tree
  * for display or to use in a form <select> element
  *
  * List is cached for 10 minutes
  *
  * For example, if you have a tree of categories like:
  *   Miscellaneous (id = 1)
  *      Subcategory (id = 2)
  *         Sub-subcategory (id = 4)
  *   Other category (id = 3)
  * Then after calling this function you will have
  * array(1 => 'Miscellaneous',
  *       2 => 'Miscellaneous / Subcategory',
  *       4 => 'Miscellaneous / Subcategory / Sub-subcategory',
  *       3 => 'Other category');
  *
  * If you specify $requiredcapability, then only categories where the current
  * user has that capability will be added to $list.
  * If you only have $requiredcapability in a child category, not the parent,
  * then the child catgegory will still be included.
  *
  * If you specify the option $excludeid, then that category, and all its children,
  * are omitted from the tree. This is useful when you are doing something like
  * moving categories, where you do not want to allow people to move a category
  * to be the child of itself.
  *
  * See also {@link make_categories_options()}
  *
  * @param string/array $requiredcapability if given, only categories where the current
  *      user has this capability will be returned. Can also be an array of capabilities,
  *      in which case they are all required.
  * @param integer $excludeid Exclude this category and its children from the lists built.
  * @param string $separator string to use as a separator between parent and child category. Default ' / '
  * @return array of strings
  */
 public static function make_categories_list($requiredcapability = '', $excludeid = 0, $separator = ' / ')
 {
     global $DB;
     $coursecatcache = cache::make('core', 'coursecat');
     // Check if we cached the complete list of user-accessible category names ($baselist) or list of ids with requried cap ($thislist).
     $basecachekey = 'catlist';
     $baselist = $coursecatcache->get($basecachekey);
     if ($baselist !== false) {
         $baselist = false;
     }
     $thislist = false;
     if (!empty($requiredcapability)) {
         $requiredcapability = (array) $requiredcapability;
         $thiscachekey = 'catlist:' . serialize($requiredcapability);
         if ($baselist !== false && ($thislist = $coursecatcache->get($thiscachekey)) !== false) {
             $thislist = preg_split('|,|', $thislist, -1, PREG_SPLIT_NO_EMPTY);
         }
     } else {
         if ($baselist !== false) {
             $thislist = array_keys($baselist);
         }
     }
     if ($baselist === false) {
         // We don't have $baselist cached, retrieve it. Retrieve $thislist again in any case.
         $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
         $sql = "SELECT cc.id, cc.sortorder, cc.name, cc.visible, cc.parent, cc.path, {$ctxselect}\n                    FROM {course_categories} cc\n                    JOIN {context} ctx ON cc.id = ctx.instanceid AND ctx.contextlevel = :contextcoursecat\n                    ORDER BY cc.sortorder";
         $rs = $DB->get_recordset_sql($sql, array('contextcoursecat' => CONTEXT_COURSECAT));
         $baselist = array();
         $thislist = array();
         foreach ($rs as $record) {
             // If the category's parent is not visible to the user, it is not visible as well.
             if (!$record->parent || isset($baselist[$record->parent])) {
                 $context = context_coursecat::instance($record->id);
                 if (!$record->visible && !has_capability('moodle/category:viewhiddencategories', $context)) {
                     // No cap to view category, added to neither $baselist nor $thislist
                     continue;
                 }
                 $baselist[$record->id] = array('name' => format_string($record->name, true, array('context' => $context)), 'path' => $record->path);
                 if (!empty($requiredcapability) && !has_all_capabilities($requiredcapability, $context)) {
                     // No required capability, added to $baselist but not to $thislist.
                     continue;
                 }
                 $thislist[] = $record->id;
             }
         }
         $rs->close();
         $coursecatcache->set($basecachekey, $baselist);
         if (!empty($requiredcapability)) {
             $coursecatcache->set($thiscachekey, join(',', $thislist));
         }
     } else {
         if ($thislist === false) {
             // We have $baselist cached but not $thislist. Simplier query is used to retrieve.
             $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
             $sql = "SELECT ctx.instanceid id, {$ctxselect}\n                    FROM {context} ctx WHERE ctx.contextlevel = :contextcoursecat";
             $contexts = $DB->get_records_sql($sql, array('contextcoursecat' => CONTEXT_COURSECAT));
             $thislist = array();
             foreach (array_keys($baselist) as $id) {
                 context_helper::preload_from_record($contexts[$id]);
                 if (has_all_capabilities($requiredcapability, context_coursecat::instance($id))) {
                     $thislist[] = $id;
                 }
             }
             $coursecatcache->set($thiscachekey, join(',', $thislist));
         }
     }
     // Now build the array of strings to return, mind $separator and $excludeid.
     $names = array();
     foreach ($thislist as $id) {
         $path = preg_split('|/|', $baselist[$id]['path'], -1, PREG_SPLIT_NO_EMPTY);
         if (!$excludeid || !in_array($excludeid, $path)) {
             $namechunks = array();
             foreach ($path as $parentid) {
                 $namechunks[] = $baselist[$parentid]['name'];
             }
             $names[$id] = join($separator, $namechunks);
         }
     }
     return $names;
 }
예제 #21
0
 /**
  * Finds all assignment notifications that have yet to be mailed out, and mails them.
  *
  * Cron function to be run periodically according to the moodle cron.
  *
  * @return bool
  */
 public static function cron()
 {
     global $DB;
     // Only ever send a max of one days worth of updates.
     $yesterday = time() - 24 * 3600;
     $timenow = time();
     $lastcron = $DB->get_field('modules', 'lastcron', array('name' => 'assign'));
     // Collect all submissions that require mailing.
     // Submissions are included if all are true:
     //   - The assignment is visible in the gradebook.
     //   - No previous notification has been sent.
     //   - If marking workflow is not enabled, the grade was updated in the past 24 hours, or
     //     if marking workflow is enabled, the workflow state is at 'released'.
     $sql = "SELECT g.id as gradeid, a.course, a.name, a.blindmarking, a.revealidentities,\n                       g.*, g.timemodified as lastmodified, cm.id as cmid\n                 FROM {assign} a\n                 JOIN {assign_grades} g ON g.assignment = a.id\n            LEFT JOIN {assign_user_flags} uf ON uf.assignment = a.id AND uf.userid = g.userid\n                 JOIN {course_modules} cm ON cm.course = a.course AND cm.instance = a.id\n                 JOIN {modules} md ON md.id = cm.module AND md.name = 'assign'\n                 JOIN {grade_items} gri ON gri.iteminstance = a.id AND gri.courseid = a.course AND gri.itemmodule = md.name\n                 WHERE ((a.markingworkflow = 0 AND g.timemodified >= :yesterday AND g.timemodified <= :today) OR\n                        (a.markingworkflow = 1 AND uf.workflowstate = :wfreleased)) AND\n                       uf.mailed = 0 AND gri.hidden = 0\n              ORDER BY a.course, cm.id";
     $params = array('yesterday' => $yesterday, 'today' => $timenow, 'wfreleased' => ASSIGN_MARKING_WORKFLOW_STATE_RELEASED);
     $submissions = $DB->get_records_sql($sql, $params);
     if (!empty($submissions)) {
         mtrace('Processing ' . count($submissions) . ' assignment submissions ...');
         // Preload courses we are going to need those.
         $courseids = array();
         foreach ($submissions as $submission) {
             $courseids[] = $submission->course;
         }
         // Filter out duplicates.
         $courseids = array_unique($courseids);
         $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
         list($courseidsql, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
         $sql = 'SELECT c.*, ' . $ctxselect . ' FROM {course} c
              LEFT JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
                  WHERE c.id ' . $courseidsql;
         $params['contextlevel'] = CONTEXT_COURSE;
         $courses = $DB->get_records_sql($sql, $params);
         // Clean up... this could go on for a while.
         unset($courseids);
         unset($ctxselect);
         unset($courseidsql);
         unset($params);
         // Message students about new feedback.
         foreach ($submissions as $submission) {
             mtrace("Processing assignment submission {$submission->id} ...");
             // Do not cache user lookups - could be too many.
             if (!($user = $DB->get_record('user', array('id' => $submission->userid)))) {
                 mtrace('Could not find user ' . $submission->userid);
                 continue;
             }
             // Use a cache to prevent the same DB queries happening over and over.
             if (!array_key_exists($submission->course, $courses)) {
                 mtrace('Could not find course ' . $submission->course);
                 continue;
             }
             $course = $courses[$submission->course];
             if (isset($course->ctxid)) {
                 // Context has not yet been preloaded. Do so now.
                 context_helper::preload_from_record($course);
             }
             // Override the language and timezone of the "current" user, so that
             // mail is customised for the receiver.
             cron_setup_user($user, $course);
             // Context lookups are already cached.
             $coursecontext = context_course::instance($course->id);
             if (!is_enrolled($coursecontext, $user->id)) {
                 $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
                 mtrace(fullname($user) . ' not an active participant in ' . $courseshortname);
                 continue;
             }
             if (!($grader = $DB->get_record('user', array('id' => $submission->grader)))) {
                 mtrace('Could not find grader ' . $submission->grader);
                 continue;
             }
             $modinfo = get_fast_modinfo($course, $user->id);
             $cm = $modinfo->get_cm($submission->cmid);
             // Context lookups are already cached.
             $contextmodule = context_module::instance($cm->id);
             if (!$cm->uservisible) {
                 // Hold mail notification for assignments the user cannot access until later.
                 continue;
             }
             // Need to send this to the student.
             $messagetype = 'feedbackavailable';
             $eventtype = 'assign_notification';
             $updatetime = $submission->lastmodified;
             $modulename = get_string('modulename', 'assign');
             $uniqueid = 0;
             if ($submission->blindmarking && !$submission->revealidentities) {
                 $uniqueid = self::get_uniqueid_for_user_static($submission->assignment, $user->id);
             }
             $showusers = $submission->blindmarking && !$submission->revealidentities;
             self::send_assignment_notification($grader, $user, $messagetype, $eventtype, $updatetime, $cm, $contextmodule, $course, $modulename, $submission->name, $showusers, $uniqueid);
             $flags = $DB->get_record('assign_user_flags', array('userid' => $user->id, 'assignment' => $submission->assignment));
             if ($flags) {
                 $flags->mailed = 1;
                 $DB->update_record('assign_user_flags', $flags);
             } else {
                 $flags = new stdClass();
                 $flags->userid = $user->id;
                 $flags->assignment = $submission->assignment;
                 $flags->mailed = 1;
                 $DB->insert_record('assign_user_flags', $flags);
             }
             mtrace('Done');
         }
         mtrace('Done processing ' . count($submissions) . ' assignment submissions');
         cron_setup_user();
         // Free up memory just to be sure.
         unset($courses);
     }
     // Update calendar events to provide a description.
     $sql = 'SELECT id
                 FROM {assign}
                 WHERE
                     allowsubmissionsfromdate >= :lastcron AND
                     allowsubmissionsfromdate <= :timenow AND
                     alwaysshowdescription = 0';
     $params = array('lastcron' => $lastcron, 'timenow' => $timenow);
     $newlyavailable = $DB->get_records_sql($sql, $params);
     foreach ($newlyavailable as $record) {
         $cm = get_coursemodule_from_instance('assign', $record->id, 0, false, MUST_EXIST);
         $context = context_module::instance($cm->id);
         $assignment = new assign($context, null, null);
         $assignment->update_calendar($cm->id);
     }
     return true;
 }
예제 #22
0
 /**
  * Get course participants details
  *
  * @param int $courseid  course id
  * @param array $options options {
  *                                'name' => option name
  *                                'value' => option value
  *                               }
  * @return array An array of users
  */
 public static function get_enrolled_users($courseid, $options = array())
 {
     global $CFG, $USER, $DB;
     require_once $CFG->dirroot . "/user/lib.php";
     $params = self::validate_parameters(self::get_enrolled_users_parameters(), array('courseid' => $courseid, 'options' => $options));
     $withcapability = '';
     $groupid = 0;
     $onlyactive = false;
     $userfields = array();
     $limitfrom = 0;
     $limitnumber = 0;
     $sortby = 'us.id';
     $sortparams = array();
     $sortdirection = 'ASC';
     foreach ($options as $option) {
         switch ($option['name']) {
             case 'withcapability':
                 $withcapability = $option['value'];
                 break;
             case 'groupid':
                 $groupid = (int) $option['value'];
                 break;
             case 'onlyactive':
                 $onlyactive = !empty($option['value']);
                 break;
             case 'userfields':
                 $thefields = explode(',', $option['value']);
                 foreach ($thefields as $f) {
                     $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
                 }
                 break;
             case 'limitfrom':
                 $limitfrom = clean_param($option['value'], PARAM_INT);
                 break;
             case 'limitnumber':
                 $limitnumber = clean_param($option['value'], PARAM_INT);
                 break;
             case 'sortby':
                 $sortallowedvalues = array('id', 'firstname', 'lastname', 'siteorder');
                 if (!in_array($option['value'], $sortallowedvalues)) {
                     throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $option['value'] . '),' . 'allowed values are: ' . implode(',', $sortallowedvalues));
                 }
                 if ($option['value'] == 'siteorder') {
                     list($sortby, $sortparams) = users_order_by_sql('us');
                 } else {
                     $sortby = 'us.' . $option['value'];
                 }
                 break;
             case 'sortdirection':
                 $sortdirection = strtoupper($option['value']);
                 $directionallowedvalues = array('ASC', 'DESC');
                 if (!in_array($sortdirection, $directionallowedvalues)) {
                     throw new invalid_parameter_exception('Invalid value for sortdirection parameter
                     (value: ' . $sortdirection . '),' . 'allowed values are: ' . implode(',', $directionallowedvalues));
                 }
                 break;
         }
     }
     $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
     $coursecontext = context_course::instance($courseid, IGNORE_MISSING);
     if ($courseid == SITEID) {
         $context = context_system::instance();
     } else {
         $context = $coursecontext;
     }
     try {
         self::validate_context($context);
     } catch (Exception $e) {
         $exceptionparam = new stdClass();
         $exceptionparam->message = $e->getMessage();
         $exceptionparam->courseid = $params['courseid'];
         throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam);
     }
     if ($courseid == SITEID) {
         require_capability('moodle/site:viewparticipants', $context);
     } else {
         require_capability('moodle/course:viewparticipants', $context);
     }
     // to overwrite this parameter, you need role:review capability
     if ($withcapability) {
         require_capability('moodle/role:review', $coursecontext);
     }
     // need accessallgroups capability if you want to overwrite this option
     if (!empty($groupid) && !groups_is_member($groupid)) {
         require_capability('moodle/site:accessallgroups', $coursecontext);
     }
     // to overwrite this option, you need course:enrolereview permission
     if ($onlyactive) {
         require_capability('moodle/course:enrolreview', $coursecontext);
     }
     list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
     $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
     $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
     $enrolledparams['contextlevel'] = CONTEXT_USER;
     $groupjoin = '';
     if (empty($groupid) && groups_get_course_groupmode($course) == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $coursecontext)) {
         // Filter by groups the user can view.
         $usergroups = groups_get_user_groups($course->id);
         if (!empty($usergroups['0'])) {
             list($groupsql, $groupparams) = $DB->get_in_or_equal($usergroups['0'], SQL_PARAMS_NAMED);
             $groupjoin = "JOIN {groups_members} gm ON (u.id = gm.userid AND gm.groupid {$groupsql})";
             $enrolledparams = array_merge($enrolledparams, $groupparams);
         } else {
             // User doesn't belong to any group, so he can't see any user. Return an empty array.
             return array();
         }
     }
     $sql = "SELECT us.*\n                  FROM {user} us\n                  JOIN (\n                      SELECT DISTINCT u.id {$ctxselect}\n                        FROM {user} u {$ctxjoin} {$groupjoin}\n                       WHERE u.id IN ({$enrolledsql})\n                  ) q ON q.id = us.id\n                ORDER BY {$sortby} {$sortdirection}";
     $enrolledparams = array_merge($enrolledparams, $sortparams);
     $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
     $users = array();
     foreach ($enrolledusers as $user) {
         context_helper::preload_from_record($user);
         if ($userdetails = user_get_user_details($user, $course, $userfields)) {
             $users[] = $userdetails;
         }
     }
     $enrolledusers->close();
     return $users;
 }
예제 #23
0
/**
 * This function gets the list of courses that this user has a particular capability in.
 * It is still not very efficient.
 *
 * @param string $capability Capability in question
 * @param int $userid User ID or null for current user
 * @param bool $doanything True if 'doanything' is permitted (default)
 * @param string $fieldsexceptid Leave blank if you only need 'id' in the course records;
 *   otherwise use a comma-separated list of the fields you require, not including id
 * @param string $orderby If set, use a comma-separated list of fields from course
 *   table with sql modifiers (DESC) if needed
 * @return array Array of courses, may have zero entries. Or false if query failed.
 */
function get_user_capability_course($capability, $userid = null, $doanything = true, $fieldsexceptid = '', $orderby = '') {
    global $DB;

    // Convert fields list and ordering
    $fieldlist = '';
    if ($fieldsexceptid) {
        $fields = explode(',', $fieldsexceptid);
        foreach($fields as $field) {
            $fieldlist .= ',c.'.$field;
        }
    }
    if ($orderby) {
        $fields = explode(',', $orderby);
        $orderby = '';
        foreach($fields as $field) {
            if ($orderby) {
                $orderby .= ',';
            }
            $orderby .= 'c.'.$field;
        }
        $orderby = 'ORDER BY '.$orderby;
    }

    // Obtain a list of everything relevant about all courses including context.
    // Note the result can be used directly as a context (we are going to), the course
    // fields are just appended.

    $contextpreload = context_helper::get_preload_record_columns_sql('x');

    $courses = array();
    $rs = $DB->get_recordset_sql("SELECT c.id $fieldlist, $contextpreload
                                    FROM {course} c
                                    JOIN {context} x ON (c.id=x.instanceid AND x.contextlevel=".CONTEXT_COURSE.")
                                $orderby");
    // Check capability for each course in turn
    foreach ($rs as $course) {
        context_helper::preload_from_record($course);
        $context = context_course::instance($course->id);
        if (has_capability($capability, $context, $userid, $doanything)) {
            // We've got the capability. Make the record look like a course record
            // and store it
            $courses[] = $course;
        }
    }
    $rs->close();
    return empty($courses) ? false : $courses;
}
/**
 * Get all the cohorts defined anywhere in system.
 *
 * The function assumes that user capability to view/manage cohorts on system level
 * has already been verified. This function only checks if such capabilities have been
 * revoked in child (categories) contexts.
 *
 * @param int $page number of the current page
 * @param int $perpage items per page
 * @param string $search search string
 * @return array    Array(totalcohorts => int, cohorts => array, allcohorts => int)
 */
function meditraxcohort_get_all_cohorts($page = 0, $perpage = 25, $search = '')
{
    global $DB;
    $fields = "SELECT c.*, " . context_helper::get_preload_record_columns_sql('ctx');
    $countfields = "SELECT COUNT(*)";
    $sql = " FROM {cohort} c\n             JOIN {context} ctx ON ctx.id = c.contextid ";
    $params = array();
    $wheresql = '';
    if ($excludedcontexts = cohort_get_invisible_contexts()) {
        list($excludedsql, $excludedparams) = $DB->get_in_or_equal($excludedcontexts, SQL_PARAMS_NAMED, 'excl', false);
        $wheresql = ' WHERE c.contextid ' . $excludedsql;
        $params = array_merge($params, $excludedparams);
    }
    $totalcohorts = $allcohorts = $DB->count_records_sql($countfields . $sql . $wheresql, $params);
    if (!empty($search)) {
        list($searchcondition, $searchparams) = cohort_get_search_query($search, 'c');
        $wheresql .= ($wheresql ? ' AND ' : ' WHERE ') . $searchcondition;
        $params = array_merge($params, $searchparams);
        $totalcohorts = $DB->count_records_sql($countfields . $sql . $wheresql, $params);
    }
    $order = " ORDER BY c.name ASC, c.idnumber ASC";
    $cohorts = $DB->get_records_sql($fields . $sql . $wheresql . $order, $params, $page * $perpage, $perpage);
    // Preload used contexts, they will be used to check view/manage/assign capabilities and display categories names.
    foreach (array_keys($cohorts) as $key) {
        context_helper::preload_from_record($cohorts[$key]);
    }
    return array('totalcohorts' => $totalcohorts, 'cohorts' => $cohorts, 'allcohorts' => $allcohorts);
}
예제 #25
0
 /**
  * Finds all assignment notifications that have yet to be mailed out, and mails them.
  *
  * Cron function to be run periodically according to the moodle cron.
  *
  * @return bool
  */
 public static function cron()
 {
     global $DB;
     // Only ever send a max of one days worth of updates.
     $yesterday = time() - 24 * 3600;
     $timenow = time();
     // Collect all submissions from the past 24 hours that require mailing.
     $sql = 'SELECT g.id as gradeid, a.course, a.name, a.blindmarking, a.revealidentities,
                    g.*, g.timemodified as lastmodified
              FROM {assign} a
              JOIN {assign_grades} g ON g.assignment = a.id
              LEFT JOIN {assign_user_flags} uf ON uf.assignment = a.id AND uf.userid = g.userid
             WHERE g.timemodified >= :yesterday AND
                   g.timemodified <= :today AND
                   uf.mailed = 0';
     $params = array('yesterday' => $yesterday, 'today' => $timenow);
     $submissions = $DB->get_records_sql($sql, $params);
     if (empty($submissions)) {
         return true;
     }
     mtrace('Processing ' . count($submissions) . ' assignment submissions ...');
     // Preload courses we are going to need those.
     $courseids = array();
     foreach ($submissions as $submission) {
         $courseids[] = $submission->course;
     }
     // Filter out duplicates.
     $courseids = array_unique($courseids);
     $ctxselect = context_helper::get_preload_record_columns_sql('ctx');
     list($courseidsql, $params) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
     $sql = 'SELECT c.*, ' . $ctxselect . ' FROM {course} c
          LEFT JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
              WHERE c.id ' . $courseidsql;
     $params['contextlevel'] = CONTEXT_COURSE;
     $courses = $DB->get_records_sql($sql, $params);
     // Clean up... this could go on for a while.
     unset($courseids);
     unset($ctxselect);
     unset($courseidsql);
     unset($params);
     // Simple array we'll use for caching modules.
     $modcache = array();
     // Message students about new feedback.
     foreach ($submissions as $submission) {
         mtrace("Processing assignment submission {$submission->id} ...");
         // Do not cache user lookups - could be too many.
         if (!($user = $DB->get_record('user', array('id' => $submission->userid)))) {
             mtrace('Could not find user ' . $submission->userid);
             continue;
         }
         // Use a cache to prevent the same DB queries happening over and over.
         if (!array_key_exists($submission->course, $courses)) {
             mtrace('Could not find course ' . $submission->course);
             continue;
         }
         $course = $courses[$submission->course];
         if (isset($course->ctxid)) {
             // Context has not yet been preloaded. Do so now.
             context_helper::preload_from_record($course);
         }
         // Override the language and timezone of the "current" user, so that
         // mail is customised for the receiver.
         cron_setup_user($user, $course);
         // Context lookups are already cached.
         $coursecontext = context_course::instance($course->id);
         if (!is_enrolled($coursecontext, $user->id)) {
             $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
             mtrace(fullname($user) . ' not an active participant in ' . $courseshortname);
             continue;
         }
         if (!($grader = $DB->get_record('user', array('id' => $submission->grader)))) {
             mtrace('Could not find grader ' . $submission->grader);
             continue;
         }
         if (!array_key_exists($submission->assignment, $modcache)) {
             $mod = get_coursemodule_from_instance('assign', $submission->assignment, $course->id);
             if (empty($mod)) {
                 mtrace('Could not find course module for assignment id ' . $submission->assignment);
                 continue;
             }
             $modcache[$submission->assignment] = $mod;
         } else {
             $mod = $modcache[$submission->assignment];
         }
         // Context lookups are already cached.
         $contextmodule = context_module::instance($mod->id);
         if (!$mod->visible) {
             // Hold mail notification for hidden assignments until later.
             continue;
         }
         // Need to send this to the student.
         $messagetype = 'feedbackavailable';
         $eventtype = 'assign_notification';
         $updatetime = $submission->lastmodified;
         $modulename = get_string('modulename', 'assign');
         $uniqueid = 0;
         if ($submission->blindmarking && !$submission->revealidentities) {
             $uniqueid = self::get_uniqueid_for_user_static($submission->assignment, $user->id);
         }
         $showusers = $submission->blindmarking && !$submission->revealidentities;
         self::send_assignment_notification($grader, $user, $messagetype, $eventtype, $updatetime, $mod, $contextmodule, $course, $modulename, $submission->name, $showusers, $uniqueid);
         $flags = $DB->get_record('assign_user_flags', array('userid' => $user->id, 'assignment' => $submission->assignment));
         if ($flags) {
             $flags->mailed = 1;
             $DB->update_record('assign_user_flags', $flags);
         } else {
             $flags = new stdClass();
             $flags->userid = $user->id;
             $flags->assignment = $submission->assignment;
             $flags->mailed = 1;
             $DB->insert_record('assign_user_flags', $flags);
         }
         mtrace('Done');
     }
     mtrace('Done processing ' . count($submissions) . ' assignment submissions');
     cron_setup_user();
     // Free up memory just to be sure.
     unset($courses);
     unset($modcache);
     return true;
 }
예제 #26
0
    /**
     * A small functional test of accesslib functions and classes.
     * @return void
     */
    public function test_everything_in_accesslib() {
        global $USER, $SITE, $CFG, $DB, $ACCESSLIB_PRIVATE;

        $this->resetAfterTest(true);

        $generator = $this->getDataGenerator();

        // Fill the site with some real data
        $testcategories = array();
        $testcourses = array();
        $testpages = array();
        $testblocks = array();
        $allroles = $DB->get_records_menu('role', array(), 'id', 'archetype, id');

        $systemcontext = context_system::instance();
        $frontpagecontext = context_course::instance(SITEID);

        // Add block to system context
        $bi = $generator->create_block('online_users');
        context_block::instance($bi->id);
        $testblocks[] = $bi->id;

        // Some users
        $testusers = array();
        for($i=0; $i<20; $i++) {
            $user = $generator->create_user();
            $testusers[$i] = $user->id;
            $usercontext = context_user::instance($user->id);

            // Add block to user profile
            $bi = $generator->create_block('online_users', array('parentcontextid'=>$usercontext->id));
            $testblocks[] = $bi->id;
        }
        // Deleted user - should be ignored everywhere, can not have context
        $generator->create_user(array('deleted'=>1));

        // Add block to frontpage
        $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagecontext->id));
        $frontpageblockcontext = context_block::instance($bi->id);
        $testblocks[] = $bi->id;

        // Add a resource to frontpage
        $page = $generator->create_module('page', array('course'=>$SITE->id));
        $testpages[] = $page->id;
        $frontpagepagecontext = context_module::instance($page->cmid);

        // Add block to frontpage resource
        $bi = $generator->create_block('online_users', array('parentcontextid'=>$frontpagepagecontext->id));
        $frontpagepageblockcontext = context_block::instance($bi->id);
        $testblocks[] = $bi->id;

        // Some nested course categories with courses
        $manualenrol = enrol_get_plugin('manual');
        $parentcat = 0;
        for($i=0; $i<5; $i++) {
            $cat = $generator->create_category(array('parent'=>$parentcat));
            $testcategories[] = $cat->id;
            $catcontext = context_coursecat::instance($cat->id);
            $parentcat = $cat->id;

            if ($i >=4) {
                continue;
            }

            // Add resource to each category
            $bi = $generator->create_block('online_users', array('parentcontextid'=>$catcontext->id));
            context_block::instance($bi->id);

            // Add a few courses to each category
            for($j=0; $j<6; $j++) {
                $course = $generator->create_course(array('category'=>$cat->id));
                $testcourses[] = $course->id;
                $coursecontext = context_course::instance($course->id);

                if ($j >= 5) {
                    continue;
                }
                // Add manual enrol instance
                $manualenrol->add_default_instance($DB->get_record('course', array('id'=>$course->id)));

                // Add block to each course
                $bi = $generator->create_block('online_users', array('parentcontextid'=>$coursecontext->id));
                $testblocks[] = $bi->id;

                // Add a resource to each course
                $page = $generator->create_module('page', array('course'=>$course->id));
                $testpages[] = $page->id;
                $modcontext = context_module::instance($page->cmid);

                // Add block to each module
                $bi = $generator->create_block('online_users', array('parentcontextid'=>$modcontext->id));
                $testblocks[] = $bi->id;
            }
        }

        // Make sure all contexts were created properly
        $count = 1; //system
        $count += $DB->count_records('user', array('deleted'=>0));
        $count += $DB->count_records('course_categories');
        $count += $DB->count_records('course');
        $count += $DB->count_records('course_modules');
        $count += $DB->count_records('block_instances');
        $this->assertEquals($DB->count_records('context'), $count);
        $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
        $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);


        // ====== context_helper::get_level_name() ================================

        $levels = context_helper::get_all_levels();
        foreach ($levels as $level=>$classname) {
            $name = context_helper::get_level_name($level);
            $this->assertFalse(empty($name));
        }


        // ======= context::instance_by_id(), context_xxx::instance();

        $context = context::instance_by_id($frontpagecontext->id);
        $this->assertSame($context->contextlevel, CONTEXT_COURSE);
        $this->assertFalse(context::instance_by_id(-1, IGNORE_MISSING));
        try {
            context::instance_by_id(-1);
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        $this->assertTrue(context_system::instance() instanceof context_system);
        $this->assertTrue(context_coursecat::instance($testcategories[0]) instanceof context_coursecat);
        $this->assertTrue(context_course::instance($testcourses[0]) instanceof context_course);
        $this->assertTrue(context_module::instance($testpages[0]) instanceof context_module);
        $this->assertTrue(context_block::instance($testblocks[0]) instanceof context_block);

        $this->assertFalse(context_coursecat::instance(-1, IGNORE_MISSING));
        $this->assertFalse(context_course::instance(-1, IGNORE_MISSING));
        $this->assertFalse(context_module::instance(-1, IGNORE_MISSING));
        $this->assertFalse(context_block::instance(-1, IGNORE_MISSING));
        try {
            context_coursecat::instance(-1);
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        try {
            context_course::instance(-1);
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        try {
            context_module::instance(-1);
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        try {
            context_block::instance(-1);
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }


        // ======= $context->get_url(), $context->get_context_name(), $context->get_capabilities() =========

        $testcontexts = array();
        $testcontexts[CONTEXT_SYSTEM]    = context_system::instance();
        $testcontexts[CONTEXT_COURSECAT] = context_coursecat::instance($testcategories[0]);
        $testcontexts[CONTEXT_COURSE]    = context_course::instance($testcourses[0]);
        $testcontexts[CONTEXT_MODULE]    = context_module::instance($testpages[0]);
        $testcontexts[CONTEXT_BLOCK]     = context_block::instance($testblocks[0]);

        foreach ($testcontexts as $context) {
            $name = $context->get_context_name(true, true);
            $this->assertFalse(empty($name));

            $this->assertTrue($context->get_url() instanceof moodle_url);

            $caps = $context->get_capabilities();
            $this->assertTrue(is_array($caps));
            foreach ($caps as $cap) {
                $cap = (array)$cap;
                $this->assertSame(array_keys($cap), array('id', 'name', 'captype', 'contextlevel', 'component', 'riskbitmask'));
            }
        }
        unset($testcontexts);

        // ===== $context->get_course_context() =========================================

        $this->assertFalse($systemcontext->get_course_context(false));
        try {
            $systemcontext->get_course_context();
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        $context = context_coursecat::instance($testcategories[0]);
        $this->assertFalse($context->get_course_context(false));
        try {
            $context->get_course_context();
            $this->fail('exception expected');
        } catch (Exception $e) {
            $this->assertTrue(true);
        }
        $this->assertSame($frontpagecontext->get_course_context(true), $frontpagecontext);
        $this->assertSame($frontpagepagecontext->get_course_context(true), $frontpagecontext);
        $this->assertSame($frontpagepageblockcontext->get_course_context(true), $frontpagecontext);


        // ======= $context->get_parent_context(), $context->get_parent_contexts(), $context->get_parent_context_ids() =======

        $userid = reset($testusers);
        $usercontext = context_user::instance($userid);
        $this->assertSame($usercontext->get_parent_context(), $systemcontext);
        $this->assertSame($usercontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext));
        $this->assertSame($usercontext->get_parent_contexts(true), array($usercontext->id=>$usercontext, $systemcontext->id=>$systemcontext));

        $this->assertSame($systemcontext->get_parent_contexts(), array());
        $this->assertSame($systemcontext->get_parent_contexts(true), array($systemcontext->id=>$systemcontext));
        $this->assertSame($systemcontext->get_parent_context_ids(), array());
        $this->assertSame($systemcontext->get_parent_context_ids(true), array($systemcontext->id));

        $this->assertSame($frontpagecontext->get_parent_context(), $systemcontext);
        $this->assertSame($frontpagecontext->get_parent_contexts(), array($systemcontext->id=>$systemcontext));
        $this->assertSame($frontpagecontext->get_parent_contexts(true), array($frontpagecontext->id=>$frontpagecontext, $systemcontext->id=>$systemcontext));
        $this->assertSame($frontpagecontext->get_parent_context_ids(), array($systemcontext->id));
        $this->assertEquals($frontpagecontext->get_parent_context_ids(true), array($frontpagecontext->id, $systemcontext->id));

        $this->assertSame($systemcontext->get_parent_context(), false);
        $frontpagecontext = context_course::instance($SITE->id);
        $parent = $systemcontext;
        foreach ($testcategories as $catid) {
            $catcontext = context_coursecat::instance($catid);
            $this->assertSame($catcontext->get_parent_context(), $parent);
            $parent = $catcontext;
        }
        $this->assertSame($frontpagepagecontext->get_parent_context(), $frontpagecontext);
        $this->assertSame($frontpageblockcontext->get_parent_context(), $frontpagecontext);
        $this->assertSame($frontpagepageblockcontext->get_parent_context(), $frontpagepagecontext);


        // ====== $context->get_child_contexts() ================================

        $CFG->debug = 0;
        $children = $systemcontext->get_child_contexts();
        $CFG->debug = DEBUG_DEVELOPER;
        $this->assertEquals(count($children)+1, $DB->count_records('context'));

        $context = context_coursecat::instance($testcategories[3]);
        $children = $context->get_child_contexts();
        $countcats    = 0;
        $countcourses = 0;
        $countblocks  = 0;
        foreach ($children as $child) {
            if ($child->contextlevel == CONTEXT_COURSECAT) {
                $countcats++;
            }
            if ($child->contextlevel == CONTEXT_COURSE) {
                $countcourses++;
            }
            if ($child->contextlevel == CONTEXT_BLOCK) {
                $countblocks++;
            }
        }
        $this->assertEquals(count($children), 8);
        $this->assertEquals($countcats, 1);
        $this->assertEquals($countcourses, 6);
        $this->assertEquals($countblocks, 1);

        $context = context_course::instance($testcourses[2]);
        $children = $context->get_child_contexts();
        $this->assertEquals(count($children), 7); // depends on number of default blocks

        $context = context_module::instance($testpages[3]);
        $children = $context->get_child_contexts();
        $this->assertEquals(count($children), 1);

        $context = context_block::instance($testblocks[1]);
        $children = $context->get_child_contexts();
        $this->assertEquals(count($children), 0);

        unset($children);
        unset($countcats);
        unset($countcourses);
        unset($countblocks);


        // ======= context_helper::reset_caches() ============================

        context_helper::reset_caches();
        $this->assertEquals(context_inspection::test_context_cache_size(), 0);
        context_course::instance($SITE->id);
        $this->assertEquals(context_inspection::test_context_cache_size(), 1);


        // ======= context preloading ========================================

        context_helper::reset_caches();
        $sql = "SELECT ".context_helper::get_preload_record_columns_sql('c')."
                  FROM {context} c
                 WHERE c.contextlevel <> ".CONTEXT_SYSTEM;
        $records = $DB->get_records_sql($sql);
        $firstrecord = reset($records);
        $columns = context_helper::get_preload_record_columns('c');
        $firstrecord = (array)$firstrecord;
        $this->assertSame(array_keys($firstrecord), array_values($columns));
        context_helper::reset_caches();
        foreach ($records as $record) {
            context_helper::preload_from_record($record);
            $this->assertEquals($record, new stdClass());
        }
        $this->assertEquals(context_inspection::test_context_cache_size(), count($records));
        unset($records);
        unset($columns);

        context_helper::reset_caches();
        context_helper::preload_course($SITE->id);
        $this->assertEquals(7, context_inspection::test_context_cache_size()); // depends on number of default blocks

        // ====== assign_capability(), unassign_capability() ====================

        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertFalse($rc);
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext->id);
        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertEquals($rc->permission, CAP_ALLOW);
        assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext->id);
        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertEquals($rc->permission, CAP_ALLOW);
        assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $allroles['teacher'], $frontpagecontext, true);
        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertEquals($rc->permission, CAP_PREVENT);

        assign_capability('moodle/site:accessallgroups', CAP_INHERIT, $allroles['teacher'], $frontpagecontext);
        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertFalse($rc);
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $allroles['teacher'], $frontpagecontext);
        unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext, true);
        $rc = $DB->get_record('role_capabilities', array('contextid'=>$frontpagecontext->id, 'roleid'=>$allroles['teacher'], 'capability'=>'moodle/site:accessallgroups'));
        $this->assertFalse($rc);
        unassign_capability('moodle/site:accessallgroups', $allroles['teacher'], $frontpagecontext->id, true);
        unset($rc);

        accesslib_clear_all_caches(false); // must be done after assign_capability()


        // ======= role_assign(), role_unassign(), role_unassign_all() ==============

        $context = context_course::instance($testcourses[1]);
        $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0);
        role_assign($allroles['teacher'], $testusers[1], $context->id);
        role_assign($allroles['teacher'], $testusers[2], $context->id);
        role_assign($allroles['manager'], $testusers[1], $context->id);
        $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 3);
        role_unassign($allroles['teacher'], $testusers[1], $context->id);
        $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 2);
        role_unassign_all(array('contextid'=>$context->id));
        $this->assertEquals($DB->count_records('role_assignments', array('contextid'=>$context->id)), 0);
        unset($context);

        accesslib_clear_all_caches(false); // just in case


        // ====== has_capability(), get_users_by_capability(), role_switch(), reload_all_capabilities() and friends ========================

        $adminid = get_admin()->id;
        $guestid = $CFG->siteguest;

        // Enrol some users into some courses
        $course1 = $DB->get_record('course', array('id'=>$testcourses[22]), '*', MUST_EXIST);
        $course2 = $DB->get_record('course', array('id'=>$testcourses[7]), '*', MUST_EXIST);
        $cms = $DB->get_records('course_modules', array('course'=>$course1->id), 'id');
        $cm1 = reset($cms);
        $blocks = $DB->get_records('block_instances', array('parentcontextid'=>context_module::instance($cm1->id)->id), 'id');
        $block1 = reset($blocks);
        $instance1 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course1->id));
        $instance2 = $DB->get_record('enrol', array('enrol'=>'manual', 'courseid'=>$course2->id));
        for($i=0; $i<9; $i++) {
            $manualenrol->enrol_user($instance1, $testusers[$i], $allroles['student']);
        }
        $manualenrol->enrol_user($instance1, $testusers[8], $allroles['teacher']);
        $manualenrol->enrol_user($instance1, $testusers[9], $allroles['editingteacher']);

        for($i=10; $i<15; $i++) {
            $manualenrol->enrol_user($instance2, $testusers[$i], $allroles['student']);
        }
        $manualenrol->enrol_user($instance2, $testusers[15], $allroles['editingteacher']);

        // Add tons of role assignments - the more the better
        role_assign($allroles['coursecreator'], $testusers[11], context_coursecat::instance($testcategories[2]));
        role_assign($allroles['manager'], $testusers[12], context_coursecat::instance($testcategories[1]));
        role_assign($allroles['student'], $testusers[9], context_module::instance($cm1->id));
        role_assign($allroles['teacher'], $testusers[8], context_module::instance($cm1->id));
        role_assign($allroles['guest'], $testusers[13], context_course::instance($course1->id));
        role_assign($allroles['teacher'], $testusers[7], context_block::instance($block1->id));
        role_assign($allroles['manager'], $testusers[9], context_block::instance($block1->id));
        role_assign($allroles['editingteacher'], $testusers[9], context_course::instance($course1->id));

        role_assign($allroles['teacher'], $adminid, context_course::instance($course1->id));
        role_assign($allroles['editingteacher'], $adminid, context_block::instance($block1->id));

        // Add tons of overrides - the more the better
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpageblockcontext, true);
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpageblockcontext, true);
        assign_capability('moodle/block:view', CAP_PROHIBIT, $allroles['guest'], $frontpageblockcontext, true);
        assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['user'], $frontpageblockcontext, true);
        assign_capability('block/online_users:viewlist', CAP_PREVENT, $allroles['student'], $frontpageblockcontext, true);

        assign_capability('moodle/site:accessallgroups', CAP_PREVENT, $CFG->defaultuserroleid, $frontpagepagecontext, true);
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagepagecontext, true);
        assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $frontpagepagecontext, true);
        assign_capability('mod/page:view', CAP_ALLOW, $allroles['user'], $frontpagepagecontext, true);
        assign_capability('moodle/page:view', CAP_ALLOW, $allroles['student'], $frontpagepagecontext, true);

        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultuserroleid, $frontpagecontext, true);
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $CFG->defaultfrontpageroleid, $frontpagecontext, true);
        assign_capability('mod/page:view', CAP_ALLOW, $allroles['guest'], $frontpagecontext, true);
        assign_capability('mod/page:view', CAP_PROHIBIT, $allroles['user'], $frontpagecontext, true);

        assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true);

        accesslib_clear_all_caches(false); // must be done after assign_capability()

        // Extra tests for guests and not-logged-in users because they can not be verified by cross checking
        // with get_users_by_capability() where they are ignored
        $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, $guestid));
        $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, $guestid));
        $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, $guestid));
        $this->assertFalse(has_capability('mod/page:view', $systemcontext, $guestid));

        $this->assertFalse(has_capability('moodle/block:view', $frontpageblockcontext, 0));
        $this->assertFalse(has_capability('mod/page:view', $frontpagepagecontext, 0));
        $this->assertTrue(has_capability('mod/page:view', $frontpagecontext, 0));
        $this->assertFalse(has_capability('mod/page:view', $systemcontext, 0));

        $this->assertFalse(has_capability('moodle/course:create', $systemcontext, $testusers[11]));
        $this->assertTrue(has_capability('moodle/course:create', context_coursecat::instance($testcategories[2]), $testusers[11]));
        $this->assertFalse(has_capability('moodle/course:create', context_course::instance($testcourses[1]), $testusers[11]));
        $this->assertTrue(has_capability('moodle/course:create', context_course::instance($testcourses[19]), $testusers[11]));

        $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[1]), $testusers[9]));
        $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9]));
        $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9]));

        // Test the list of enrolled users
        $coursecontext = context_course::instance($course1->id);
        $enrolled = get_enrolled_users($coursecontext);
        $this->assertEquals(count($enrolled), 10);
        for($i=0; $i<10; $i++) {
            $this->assertTrue(isset($enrolled[$testusers[$i]]));
        }
        $enrolled = get_enrolled_users($coursecontext, 'moodle/course:update');
        $this->assertEquals(count($enrolled), 1);
        $this->assertTrue(isset($enrolled[$testusers[9]]));
        unset($enrolled);

        // role switching
        $userid = $testusers[9];
        $USER = $DB->get_record('user', array('id'=>$userid));
        load_all_capabilities();
        $coursecontext = context_course::instance($course1->id);
        $this->assertTrue(has_capability('moodle/course:update', $coursecontext));
        $this->assertFalse(is_role_switched($course1->id));
        role_switch($allroles['student'], $coursecontext);
        $this->assertTrue(is_role_switched($course1->id));
        $this->assertEquals($USER->access['rsw'][$coursecontext->path],  $allroles['student']);
        $this->assertFalse(has_capability('moodle/course:update', $coursecontext));
        reload_all_capabilities();
        $this->assertFalse(has_capability('moodle/course:update', $coursecontext));
        role_switch(0, $coursecontext);
        $this->assertTrue(has_capability('moodle/course:update', $coursecontext));
        $userid = $adminid;
        $USER = $DB->get_record('user', array('id'=>$userid));
        load_all_capabilities();
        $coursecontext = context_course::instance($course1->id);
        $blockcontext = context_block::instance($block1->id);
        $this->assertTrue(has_capability('moodle/course:update', $blockcontext));
        role_switch($allroles['student'], $coursecontext);
        $this->assertEquals($USER->access['rsw'][$coursecontext->path],  $allroles['student']);
        $this->assertFalse(has_capability('moodle/course:update', $blockcontext));
        reload_all_capabilities();
        $this->assertFalse(has_capability('moodle/course:update', $blockcontext));
        load_all_capabilities();
        $this->assertTrue(has_capability('moodle/course:update', $blockcontext));

        // temp course role for enrol
        $DB->delete_records('cache_flags', array()); // this prevents problem with dirty contexts immediately resetting the temp role - this is a known problem...
        $userid = $testusers[5];
        $roleid = $allroles['editingteacher'];
        $USER = $DB->get_record('user', array('id'=>$userid));
        load_all_capabilities();
        $coursecontext = context_course::instance($course1->id);
        $this->assertFalse(has_capability('moodle/course:update', $coursecontext));
        $this->assertFalse(isset($USER->access['ra'][$coursecontext->path][$roleid]));
        load_temp_course_role($coursecontext, $roleid);
        $this->assertEquals($USER->access['ra'][$coursecontext->path][$roleid], $roleid);
        $this->assertTrue(has_capability('moodle/course:update', $coursecontext));
        remove_temp_course_roles($coursecontext);
        $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid));
        load_temp_course_role($coursecontext, $roleid);
        reload_all_capabilities();
        $this->assertFalse(has_capability('moodle/course:update', $coursecontext, $userid));
        $USER = new stdClass();
        $USER->id = 0;

        // Now cross check has_capability() with get_users_by_capability(), each using different code paths,
        // they have to be kept in sync, usually only one of them breaks, so we know when something is wrong,
        // at the same time validate extra restrictions (guest read only no risks, admin exception, non existent and deleted users)
        $contexts = $DB->get_records('context', array(), 'id');
        $contexts = array_values($contexts);
        $capabilities = $DB->get_records('capabilities', array(), 'id');
        $capabilities = array_values($capabilities);
        $roles = array($allroles['guest'], $allroles['user'], $allroles['teacher'], $allroles['editingteacher'], $allroles['coursecreator'], $allroles['manager']);
        $userids = array_values($testusers);
        $userids[] = get_admin()->id;

        if (!PHPUNIT_LONGTEST) {
            $contexts = array_slice($contexts, 0, 10);
            $capabilities = array_slice($capabilities, 0, 5);
            $userids = array_slice($userids, 0, 5);
        }

        // Random time!
        //srand(666);
        foreach($userids as $userid) { // no guest or deleted
            // each user gets 0-10 random roles
            $rcount = rand(0, 10);
            for($j=0; $j<$rcount; $j++) {
                $roleid = $roles[rand(0, count($roles)-1)];
                $contextid = $contexts[rand(0, count($contexts)-1)]->id;
                role_assign($roleid, $userid, $contextid);
            }
        }

        $permissions = array(CAP_ALLOW, CAP_PREVENT, CAP_INHERIT, CAP_PREVENT);
        $maxoverrides = count($contexts)*10;
        for($j=0; $j<$maxoverrides; $j++) {
            $roleid = $roles[rand(0, count($roles)-1)];
            $contextid = $contexts[rand(0, count($contexts)-1)]->id;
            $permission = $permissions[rand(0,count($permissions)-1)];
            $capname = $capabilities[rand(0, count($capabilities)-1)]->name;
            assign_capability($capname, $permission, $roleid, $contextid, true);
        }
        unset($permissions);
        unset($roles);

        accesslib_clear_all_caches(false); // must be done after assign_capability()

        // Test time - let's set up some real user, just in case the logic for USER affects the others...
        $USER = $DB->get_record('user', array('id'=>$testusers[3]));
        load_all_capabilities();

        $userids[] = $CFG->siteguest;
        $userids[] = 0; // not-logged-in user
        $userids[] = -1; // non-existent user

        foreach ($contexts as $crecord) {
            $context = context::instance_by_id($crecord->id);
            if ($coursecontext = $context->get_course_context(false)) {
                $enrolled = get_enrolled_users($context);
            } else {
                $enrolled = array();
            }
            foreach ($capabilities as $cap) {
                $allowed = get_users_by_capability($context, $cap->name, 'u.id, u.username');
                if ($enrolled) {
                    $enrolledwithcap = get_enrolled_users($context, $cap->name);
                } else {
                    $enrolledwithcap = array();
                }
                foreach ($userids as $userid) {
                    if ($userid == 0 or isguestuser($userid)) {
                        if ($userid == 0) {
                            $CFG->forcelogin = true;
                            $this->assertFalse(has_capability($cap->name, $context, $userid));
                            unset($CFG->forcelogin);
                        }
                        if (($cap->captype === 'write') or ($cap->riskbitmask & (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))) {
                            $this->assertFalse(has_capability($cap->name, $context, $userid));
                        }
                        $this->assertFalse(isset($allowed[$userid]));
                    } else {
                        if (is_siteadmin($userid)) {
                            $this->assertTrue(has_capability($cap->name, $context, $userid, true));
                        }
                        $hascap = has_capability($cap->name, $context, $userid, false);
                        $this->assertSame($hascap, isset($allowed[$userid]), "Capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." ");
                        if (isset($enrolled[$userid])) {
                            $this->assertSame(isset($allowed[$userid]), isset($enrolledwithcap[$userid]), "Enrolment with capability result mismatch user:$userid, context:$context->id, $cap->name, hascap: ".(int)$hascap." ");
                        }
                    }
                }
            }
        }
        // Back to nobody
        $USER = new stdClass();
        $USER->id = 0;
        unset($contexts);
        unset($userids);
        unset($capabilities);

        // Now let's do all the remaining tests that break our carefully prepared fake site



        // ======= $context->mark_dirty() =======================================

        $DB->delete_records('cache_flags', array());
        accesslib_clear_all_caches(false);
        $systemcontext->mark_dirty();
        $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
        $this->assertTrue(isset($dirty[$systemcontext->path]));
        $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$systemcontext->path]));


        // ======= $context->reload_if_dirty(); =================================

        $DB->delete_records('cache_flags', array());
        accesslib_clear_all_caches(false);
        load_all_capabilities();
        $context = context_course::instance($testcourses[2]);
        $page = $DB->get_record('page', array('course'=>$testcourses[2]));
        $pagecontext = context_module::instance($page->id);

        $context->mark_dirty();
        $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path]));
        $USER->access['test'] = true;
        $context->reload_if_dirty();
        $this->assertFalse(isset($USER->access['test']));

        $context->mark_dirty();
        $this->assertTrue(isset($ACCESSLIB_PRIVATE->dirtycontexts[$context->path]));
        $USER->access['test'] = true;
        $pagecontext->reload_if_dirty();
        $this->assertFalse(isset($USER->access['test']));


        // ======= context_helper::build_all_paths() ============================

        $oldcontexts = $DB->get_records('context', array(), 'id');
        $DB->set_field_select('context', 'path', NULL, "contextlevel <> ".CONTEXT_SYSTEM);
        $DB->set_field_select('context', 'depth', 0, "contextlevel <> ".CONTEXT_SYSTEM);
        context_helper::build_all_paths();
        $newcontexts = $DB->get_records('context', array(), 'id');
        $this->assertEquals($oldcontexts, $newcontexts);
        unset($oldcontexts);
        unset($newcontexts);


        // ======= $context->reset_paths() ======================================

        $context = context_course::instance($testcourses[2]);
        $children = $context->get_child_contexts();
        $context->reset_paths(false);
        $this->assertSame($DB->get_field('context', 'path', array('id'=>$context->id)), NULL);
        $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), 0);
        foreach ($children as $child) {
            $this->assertSame($DB->get_field('context', 'path', array('id'=>$child->id)), NULL);
            $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$child->id)), 0);
        }
        $this->assertEquals(count($children)+1, $DB->count_records('context', array('depth'=>0)));
        $this->assertEquals(count($children)+1, $DB->count_records('context', array('path'=>NULL)));

        $context = context_course::instance($testcourses[2]);
        $context->reset_paths(true);
        $context = context_course::instance($testcourses[2]);
        $this->assertEquals($DB->get_field('context', 'path', array('id'=>$context->id)), $context->path);
        $this->assertEquals($DB->get_field('context', 'depth', array('id'=>$context->id)), $context->depth);
        $this->assertEquals(0, $DB->count_records('context', array('depth'=>0)));
        $this->assertEquals(0, $DB->count_records('context', array('path'=>NULL)));


        // ====== $context->update_moved(); ======================================

        accesslib_clear_all_caches(false);
        $DB->delete_records('cache_flags', array());
        $course = $DB->get_record('course', array('id'=>$testcourses[0]));
        $context = context_course::instance($course->id);
        $oldpath = $context->path;
        $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
        $categorycontext = context_coursecat::instance($miscid);
        $course->category = $miscid;
        $DB->update_record('course', $course);
        $context->update_moved($categorycontext);

        $context = context_course::instance($course->id);
        $this->assertEquals($context->get_parent_context(), $categorycontext);
        $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
        $this->assertTrue(isset($dirty[$oldpath]));
        $this->assertTrue(isset($dirty[$context->path]));


        // ====== $context->delete_content() =====================================

        context_helper::reset_caches();
        $context = context_module::instance($testpages[3]);
        $this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
        $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
        $context->delete_content();
        $this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
        $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));


        // ====== $context->delete() =============================

        context_helper::reset_caches();
        $context = context_module::instance($testpages[4]);
        $this->assertTrue($DB->record_exists('context', array('id'=>$context->id)));
        $this->assertEquals(1, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
        $bi = $DB->get_record('block_instances', array('parentcontextid'=>$context->id));
        $bicontext = context_block::instance($bi->id);
        $DB->delete_records('cache_flags', array());
        $context->delete(); // should delete also linked blocks
        $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
        $this->assertTrue(isset($dirty[$context->path]));
        $this->assertFalse($DB->record_exists('context', array('id'=>$context->id)));
        $this->assertFalse($DB->record_exists('context', array('id'=>$bicontext->id)));
        $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_MODULE, 'instanceid'=>$testpages[4])));
        $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK, 'instanceid'=>$bi->id)));
        $this->assertEquals(0, $DB->count_records('block_instances', array('parentcontextid'=>$context->id)));
        context_module::instance($testpages[4]);


        // ====== context_helper::delete_instance() =============================

        context_helper::reset_caches();
        $lastcourse = array_pop($testcourses);
        $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse)));
        $coursecontext = context_course::instance($lastcourse);
        $this->assertEquals(context_inspection::test_context_cache_size(), 1);
        $this->assertFalse($coursecontext->instanceid == CONTEXT_COURSE);
        $DB->delete_records('cache_flags', array());
        context_helper::delete_instance(CONTEXT_COURSE, $lastcourse);
        $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
        $this->assertTrue(isset($dirty[$coursecontext->path]));
        $this->assertEquals(context_inspection::test_context_cache_size(), 0);
        $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$lastcourse)));
        context_course::instance($lastcourse);


        // ======= context_helper::create_instances() ==========================

        $prevcount = $DB->count_records('context');
        $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
        context_helper::create_instances(null, true);
        $this->assertSame($DB->count_records('context'), $prevcount);
        $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
        $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);

        $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
        $DB->delete_records('block_instances', array());
        $prevcount = $DB->count_records('context');
        $DB->delete_records_select('context', 'contextlevel <> '.CONTEXT_SYSTEM);
        context_helper::create_instances(null, true);
        $this->assertSame($DB->count_records('context'), $prevcount);
        $this->assertEquals($DB->count_records('context', array('depth'=>0)), 0);
        $this->assertEquals($DB->count_records('context', array('path'=>NULL)), 0);


        // ======= context_helper::cleanup_instances() ==========================

        $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}");
        $DB->delete_records('course', array('id'=>$lastcourse));
        $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}");
        $DB->delete_records('course_categories', array('id'=>$lastcategory));
        $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0");
        $DB->delete_records('user', array('id'=>$lastuser));
        $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id));
        $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid));
        context_helper::cleanup_instances();
        $count = 1; //system
        $count += $DB->count_records('user', array('deleted'=>0));
        $count += $DB->count_records('course_categories');
        $count += $DB->count_records('course');
        $count += $DB->count_records('course_modules');
        $count += $DB->count_records('block_instances');
        $this->assertEquals($DB->count_records('context'), $count);


        // ======= context cache size restrictions ==============================

        $testusers= array();
        for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) {
            $user = $generator->create_user();
            $testusers[$i] = $user->id;
        }
        context_helper::create_instances(null, true);
        context_helper::reset_caches();
        for ($i=0; $i<CONTEXT_CACHE_MAX_SIZE + 100; $i++) {
            context_user::instance($testusers[$i]);
            if ($i == CONTEXT_CACHE_MAX_SIZE - 1) {
                $this->assertEquals(context_inspection::test_context_cache_size(), CONTEXT_CACHE_MAX_SIZE);
            } else if ($i == CONTEXT_CACHE_MAX_SIZE) {
                // once the limit is reached roughly 1/3 of records should be removed from cache
                $this->assertEquals(context_inspection::test_context_cache_size(), (int)(CONTEXT_CACHE_MAX_SIZE * (2/3) +102));
            }
        }
        // We keep the first 100 cached
        $prevsize = context_inspection::test_context_cache_size();
        for ($i=0; $i<100; $i++) {
            context_user::instance($testusers[$i]);
            $this->assertEquals(context_inspection::test_context_cache_size(), $prevsize);
        }
        context_user::instance($testusers[102]);
        $this->assertEquals(context_inspection::test_context_cache_size(), $prevsize+1);
        unset($testusers);



        // =================================================================
        // ======= basic test of legacy functions ==========================
        // =================================================================
        // note: watch out, the fake site might be pretty borked already

        $this->assertSame(get_system_context(), context_system::instance());

        foreach ($DB->get_records('context') as $contextid=>$record) {
            $context = context::instance_by_id($contextid);
            $this->assertSame(get_context_instance_by_id($contextid), $context);
            $this->assertSame(get_context_instance($record->contextlevel, $record->instanceid), $context);
            $this->assertSame(get_parent_contexts($context), $context->get_parent_context_ids());
            if ($context->id == SYSCONTEXTID) {
                $this->assertSame(get_parent_contextid($context), false);
            } else {
                $this->assertSame(get_parent_contextid($context), $context->get_parent_context()->id);
            }
        }

        $CFG->debug = 0;
        $children = get_child_contexts($systemcontext);
        $CFG->debug = DEBUG_DEVELOPER;
        $this->assertEquals(count($children), $DB->count_records('context')-1);
        unset($children);

        $DB->delete_records('context', array('contextlevel'=>CONTEXT_BLOCK));
        create_contexts();
        $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_BLOCK)));

        $DB->set_field('context', 'depth', 0, array('contextlevel'=>CONTEXT_BLOCK));
        build_context_path();
        $this->assertFalse($DB->record_exists('context', array('depth'=>0)));

        $lastcourse = $DB->get_field_sql("SELECT MAX(id) FROM {course}");
        $DB->delete_records('course', array('id'=>$lastcourse));
        $lastcategory = $DB->get_field_sql("SELECT MAX(id) FROM {course_categories}");
        $DB->delete_records('course_categories', array('id'=>$lastcategory));
        $lastuser = $DB->get_field_sql("SELECT MAX(id) FROM {user} WHERE deleted=0");
        $DB->delete_records('user', array('id'=>$lastuser));
        $DB->delete_records('block_instances', array('parentcontextid'=>$frontpagepagecontext->id));
        $DB->delete_records('course_modules', array('id'=>$frontpagepagecontext->instanceid));
        cleanup_contexts();
        $count = 1; //system
        $count += $DB->count_records('user', array('deleted'=>0));
        $count += $DB->count_records('course_categories');
        $count += $DB->count_records('course');
        $count += $DB->count_records('course_modules');
        $count += $DB->count_records('block_instances');
        $this->assertEquals($DB->count_records('context'), $count);

        context_helper::reset_caches();
        preload_course_contexts($SITE->id);
        $this->assertEquals(context_inspection::test_context_cache_size(), 1);

        context_helper::reset_caches();
        list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSECAT, 'ctx');
        $sql = "SELECT c.id $select FROM {course_categories} c $join";
        $records = $DB->get_records_sql($sql);
        foreach ($records as $record) {
            context_instance_preload($record);
            $record = (array)$record;
            $this->assertEquals(1, count($record)); // only id left
        }
        $this->assertEquals(count($records), context_inspection::test_context_cache_size());

        accesslib_clear_all_caches(true);
        $DB->delete_records('cache_flags', array());
        mark_context_dirty($systemcontext->path);
        $dirty = get_cache_flags('accesslib/dirtycontexts', time()-2);
        $this->assertTrue(isset($dirty[$systemcontext->path]));

        accesslib_clear_all_caches(false);
        $DB->delete_records('cache_flags', array());
        $course = $DB->get_record('course', array('id'=>$testcourses[2]));
        $context = get_context_instance(CONTEXT_COURSE, $course->id);
        $oldpath = $context->path;
        $miscid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
        $categorycontext = context_coursecat::instance($miscid);
        $course->category = $miscid;
        $DB->update_record('course', $course);
        context_moved($context, $categorycontext);
        $context = get_context_instance(CONTEXT_COURSE, $course->id);
        $this->assertEquals($context->get_parent_context(), $categorycontext);

        $this->assertTrue($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2])));
        delete_context(CONTEXT_COURSE, $testcourses[2]);
        $this->assertFalse($DB->record_exists('context', array('contextlevel'=>CONTEXT_COURSE, 'instanceid'=>$testcourses[2])));

        $name = get_contextlevel_name(CONTEXT_COURSE);
        $this->assertFalse(empty($name));

        $context = get_context_instance(CONTEXT_COURSE, $testcourses[2]);
        $name = print_context_name($context);
        $this->assertFalse(empty($name));

        $url = get_context_url($coursecontext);
        $this->assertFalse($url instanceof modole_url);

        $page = $DB->get_record('page', array('id'=>$testpages[7]));
        $context = get_context_instance(CONTEXT_MODULE, $page->id);
        $coursecontext = get_course_context($context);
        $this->assertEquals($coursecontext->contextlevel, CONTEXT_COURSE);
        $this->assertEquals(get_courseid_from_context($context), $page->course);

        $caps = fetch_context_capabilities($systemcontext);
        $this->assertTrue(is_array($caps));
        unset($caps);
    }
예제 #27
0
    if ($accesssince) {
        $wheres[] = get_user_lastaccess_sql($accesssince);
    }
} else {
    $select = "SELECT {$mainuserfields}, COALESCE(ul.timeaccess, 0) AS lastaccess{$extrasql}";
    $joins[] = "JOIN ({$esql}) e ON e.id = u.id";
    // Course enrolled users only.
    $joins[] = "LEFT JOIN {user_lastaccess} ul ON (ul.userid = u.id AND ul.courseid = :courseid)";
    // Not everybody accessed course yet.
    $params['courseid'] = $course->id;
    if ($accesssince) {
        $wheres[] = get_course_lastaccess_sql($accesssince);
    }
}
// Performance hacks - we preload user contexts together with accounts.
$ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
$ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
$params['contextlevel'] = CONTEXT_USER;
$select .= $ccselect;
$joins[] = $ccjoin;
// Limit list to users with some role only.
if ($roleid) {
    // We want to query both the current context and parent contexts.
    list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx');
    $wheres[] = "u.id IN (SELECT userid FROM {role_assignments} WHERE roleid = :roleid AND contextid {$relatedctxsql})";
    $params = array_merge($params, array('roleid' => $roleid), $relatedctxparams);
}
$from = implode("\n", $joins);
if ($wheres) {
    $where = "WHERE " . implode(" AND ", $wheres);
} else {
예제 #28
0
/**
 * Preloads context information together with instances.
 * Use context_instance_preload() to strip the context info from the record and cache the context instance.
 *
 * If you are using this methid, you should have something like this:
 *
 *    list($ctxselect, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
 *
 * To prevent the use of this deprecated function, replace the line above with something similar to this:
 *
 *    $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
 *                                                                        ^
 *    $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
 *                                    ^       ^                ^        ^
 *    $params = array('contextlevel' => CONTEXT_COURSE);
 *                                      ^
 * @see context_helper:;get_preload_record_columns_sql()
 * @deprecated since 2.2
 * @param string $joinon for example 'u.id'
 * @param string $contextlevel context level of instance in $joinon
 * @param string $tablealias context table alias
 * @return array with two values - select and join part
 */
function context_instance_preload_sql($joinon, $contextlevel, $tablealias)
{
    debugging('context_instance_preload_sql() is deprecated, please use context_helper::get_preload_record_columns_sql() instead.', DEBUG_DEVELOPER);
    $select = ", " . context_helper::get_preload_record_columns_sql($tablealias);
    $join = "LEFT JOIN {context} {$tablealias} ON ({$tablealias}.instanceid = {$joinon} AND {$tablealias}.contextlevel = {$contextlevel})";
    return array($select, $join);
}
예제 #29
0
 /**
  * This function gets called by {@link settings_navigation::load_user_settings()} and actually works out
  * what can be shown/done
  *
  * @param int $courseid The current course' id
  * @param int $userid The user id to load for
  * @param string $gstitle The string to pass to get_string for the branch title
  * @return navigation_node|false
  */
 protected function generate_user_settings($courseid, $userid, $gstitle = 'usercurrentsettings')
 {
     global $DB, $CFG, $USER, $SITE;
     if ($courseid != $SITE->id) {
         if (!empty($this->page->course->id) && $this->page->course->id == $courseid) {
             $course = $this->page->course;
         } else {
             $select = context_helper::get_preload_record_columns_sql('ctx');
             $sql = "SELECT c.*, {$select}\n                          FROM {course} c\n                          JOIN {context} ctx ON c.id = ctx.instanceid\n                         WHERE c.id = :courseid AND ctx.contextlevel = :contextlevel";
             $params = array('courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
             $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
             context_helper::preload_from_record($course);
         }
     } else {
         $course = $SITE;
     }
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
     // Course context
     $systemcontext = get_system_context();
     $currentuser = $USER->id == $userid;
     if ($currentuser) {
         $user = $USER;
         $usercontext = get_context_instance(CONTEXT_USER, $user->id);
         // User context
     } else {
         $select = context_helper::get_preload_record_columns_sql('ctx');
         $sql = "SELECT u.*, {$select}\n                      FROM {user} u\n                      JOIN {context} ctx ON u.id = ctx.instanceid\n                     WHERE u.id = :userid AND ctx.contextlevel = :contextlevel";
         $params = array('userid' => $userid, 'contextlevel' => CONTEXT_USER);
         $user = $DB->get_record_sql($sql, $params, IGNORE_MISSING);
         if (!$user) {
             return false;
         }
         context_helper::preload_from_record($user);
         // Check that the user can view the profile
         $usercontext = get_context_instance(CONTEXT_USER, $user->id);
         // User context
         $canviewuser = has_capability('moodle/user:viewdetails', $usercontext);
         if ($course->id == $SITE->id) {
             if ($CFG->forceloginforprofiles && !has_coursecontact_role($user->id) && !$canviewuser) {
                 // Reduce possibility of "browsing" userbase at site level
                 // Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
                 return false;
             }
         } else {
             $canviewusercourse = has_capability('moodle/user:viewdetails', $coursecontext);
             $canaccessallgroups = has_capability('moodle/site:accessallgroups', $coursecontext);
             if (!$canviewusercourse && !$canviewuser || !can_access_course($course, $user->id)) {
                 return false;
             }
             if (!$canaccessallgroups && groups_get_course_groupmode($course) == SEPARATEGROUPS) {
                 // If groups are in use, make sure we can see that group
                 return false;
             }
         }
     }
     $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $this->page->context));
     $key = $gstitle;
     if ($gstitle != 'usercurrentsettings') {
         $key .= $userid;
     }
     // Add a user setting branch
     $usersetting = $this->add(get_string($gstitle, 'moodle', $fullname), null, self::TYPE_CONTAINER, null, $key);
     $usersetting->id = 'usersettings';
     if ($this->page->context->contextlevel == CONTEXT_USER && $this->page->context->instanceid == $user->id) {
         // Automatically start by making it active
         $usersetting->make_active();
     }
     // Check if the user has been deleted
     if ($user->deleted) {
         if (!has_capability('moodle/user:update', $coursecontext)) {
             // We can't edit the user so just show the user deleted message
             $usersetting->add(get_string('userdeleted'), null, self::TYPE_SETTING);
         } else {
             // We can edit the user so show the user deleted message and link it to the profile
             if ($course->id == $SITE->id) {
                 $profileurl = new moodle_url('/user/profile.php', array('id' => $user->id));
             } else {
                 $profileurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
             }
             $usersetting->add(get_string('userdeleted'), $profileurl, self::TYPE_SETTING);
         }
         return true;
     }
     $userauthplugin = false;
     if (!empty($user->auth)) {
         $userauthplugin = get_auth_plugin($user->auth);
     }
     // Add the profile edit link
     if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
         if (($currentuser || is_siteadmin($USER) || !is_siteadmin($user)) && has_capability('moodle/user:update', $systemcontext)) {
             $url = new moodle_url('/user/editadvanced.php', array('id' => $user->id, 'course' => $course->id));
             $usersetting->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
         } else {
             if (has_capability('moodle/user:editprofile', $usercontext) && !is_siteadmin($user) || $currentuser && has_capability('moodle/user:editownprofile', $systemcontext)) {
                 if ($userauthplugin && $userauthplugin->can_edit_profile()) {
                     $url = $userauthplugin->edit_profile_url();
                     if (empty($url)) {
                         $url = new moodle_url('/user/edit.php', array('id' => $user->id, 'course' => $course->id));
                     }
                     $usersetting->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
                 }
             }
         }
     }
     // Change password link
     if ($userauthplugin && $currentuser && !session_is_loggedinas() && !isguestuser() && has_capability('moodle/user:changeownpassword', $systemcontext) && $userauthplugin->can_change_password()) {
         $passwordchangeurl = $userauthplugin->change_password_url();
         if (empty($passwordchangeurl)) {
             $passwordchangeurl = new moodle_url('/login/change_password.php', array('id' => $course->id));
         }
         $usersetting->add(get_string("changepassword"), $passwordchangeurl, self::TYPE_SETTING);
     }
     // View the roles settings
     if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage'), $usercontext)) {
         $roles = $usersetting->add(get_string('roles'), null, self::TYPE_SETTING);
         $url = new moodle_url('/admin/roles/usersroles.php', array('userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('thisusersroles', 'role'), $url, self::TYPE_SETTING);
         $assignableroles = get_assignable_roles($usercontext, ROLENAME_BOTH);
         if (!empty($assignableroles)) {
             $url = new moodle_url('/admin/roles/assign.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('assignrolesrelativetothisuser', 'role'), $url, self::TYPE_SETTING);
         }
         if (has_capability('moodle/role:review', $usercontext) || count(get_overridable_roles($usercontext, ROLENAME_BOTH)) > 0) {
             $url = new moodle_url('/admin/roles/permissions.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('permissions', 'role'), $url, self::TYPE_SETTING);
         }
         $url = new moodle_url('/admin/roles/check.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING);
     }
     // Portfolio
     if ($currentuser && !empty($CFG->enableportfolios) && has_capability('moodle/portfolio:export', $systemcontext)) {
         require_once $CFG->libdir . '/portfoliolib.php';
         if (portfolio_instances(true, false)) {
             $portfolio = $usersetting->add(get_string('portfolios', 'portfolio'), null, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfolio.php', array('courseid' => $course->id));
             $portfolio->add(get_string('configure', 'portfolio'), $url, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfoliologs.php', array('courseid' => $course->id));
             $portfolio->add(get_string('logs', 'portfolio'), $url, self::TYPE_SETTING);
         }
     }
     $enablemanagetokens = false;
     if (!empty($CFG->enablerssfeeds)) {
         $enablemanagetokens = true;
     } else {
         if (!is_siteadmin($USER->id) && !empty($CFG->enablewebservices) && has_capability('moodle/webservice:createtoken', get_system_context())) {
             $enablemanagetokens = true;
         }
     }
     // Security keys
     if ($currentuser && $enablemanagetokens) {
         $url = new moodle_url('/user/managetoken.php', array('sesskey' => sesskey()));
         $usersetting->add(get_string('securitykeys', 'webservice'), $url, self::TYPE_SETTING);
     }
     // Repository
     if (!$currentuser && $usercontext->contextlevel == CONTEXT_USER) {
         if (!$this->cache->cached('contexthasrepos' . $usercontext->id)) {
             require_once $CFG->dirroot . '/repository/lib.php';
             $editabletypes = repository::get_editable_types($usercontext);
             $haseditabletypes = !empty($editabletypes);
             unset($editabletypes);
             $this->cache->set('contexthasrepos' . $usercontext->id, $haseditabletypes);
         } else {
             $haseditabletypes = $this->cache->{'contexthasrepos' . $usercontext->id};
         }
         if ($haseditabletypes) {
             $url = new moodle_url('/repository/manage_instances.php', array('contextid' => $usercontext->id));
             $usersetting->add(get_string('repositories', 'repository'), $url, self::TYPE_SETTING);
         }
     }
     // Messaging
     if ($currentuser && has_capability('moodle/user:editownmessageprofile', $systemcontext) || !isguestuser($user) && has_capability('moodle/user:editmessageprofile', $usercontext) && !is_primary_admin($user->id)) {
         $url = new moodle_url('/message/edit.php', array('id' => $user->id));
         $usersetting->add(get_string('editmymessage', 'message'), $url, self::TYPE_SETTING);
     }
     // Blogs
     if ($currentuser && !empty($CFG->bloglevel)) {
         $blog = $usersetting->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER, null, 'blogs');
         $blog->add(get_string('preferences', 'blog'), new moodle_url('/blog/preferences.php'), navigation_node::TYPE_SETTING);
         if (!empty($CFG->useexternalblogs) && $CFG->maxexternalblogsperuser > 0 && has_capability('moodle/blog:manageexternal', get_context_instance(CONTEXT_SYSTEM))) {
             $blog->add(get_string('externalblogs', 'blog'), new moodle_url('/blog/external_blogs.php'), navigation_node::TYPE_SETTING);
             $blog->add(get_string('addnewexternalblog', 'blog'), new moodle_url('/blog/external_blog_edit.php'), navigation_node::TYPE_SETTING);
         }
     }
     // Login as ...
     if (!$user->deleted and !$currentuser && !session_is_loggedinas() && has_capability('moodle/user:loginas', $coursecontext) && !is_siteadmin($user->id)) {
         $url = new moodle_url('/course/loginas.php', array('id' => $course->id, 'user' => $user->id, 'sesskey' => sesskey()));
         $usersetting->add(get_string('loginas'), $url, self::TYPE_SETTING);
     }
     return $usersetting;
 }
예제 #30
0
 function definition()
 {
     global $CFG, $DB;
     $mform = $this->_form;
     $course = $this->_customdata['course'];
     $instance = $this->_customdata['instance'];
     $this->course = $course;
     if ($instance) {
         $where = 'WHERE c.id = :courseid';
         $params = array('courseid' => $instance->customint1);
         $existing = array();
     } else {
         $where = '';
         $params = array();
         $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $course->id), '', 'customint1, id');
     }
     // TODO: this has to be done via ajax or else it will fail very badly on large sites!
     $courses = array('' => get_string('choosedots'));
     $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
     $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
     $plugin = enrol_get_plugin('meta');
     $sortorder = 'c.' . $plugin->get_config('coursesort', 'sortorder') . ' ASC';
     $sql = "SELECT c.id, c.fullname, c.shortname, c.visible {$select} FROM {course} c {$join} {$where} ORDER BY {$sortorder}";
     $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE) + $params);
     foreach ($rs as $c) {
         if ($c->id == SITEID or $c->id == $course->id or isset($existing[$c->id])) {
             continue;
         }
         context_helper::preload_from_record($c);
         $coursecontext = context_course::instance($c->id);
         if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
             continue;
         }
         if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
             continue;
         }
         $courses[$c->id] = $coursecontext->get_context_name(false);
     }
     $rs->close();
     $groups = array(0 => get_string('none'));
     if (has_capability('moodle/course:managegroups', context_course::instance($course->id))) {
         $groups[ENROL_META_CREATE_GROUP] = get_string('creategroup', 'enrol_meta');
     }
     foreach (groups_get_all_groups($course->id) as $group) {
         $groups[$group->id] = format_string($group->name, true, array('context' => context_course::instance($course->id)));
     }
     $mform->addElement('header', 'general', get_string('pluginname', 'enrol_meta'));
     $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_meta'), $courses);
     $mform->addRule('link', get_string('required'), 'required', null, 'client');
     $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups);
     $mform->addElement('hidden', 'id', null);
     $mform->setType('id', PARAM_INT);
     $mform->addElement('hidden', 'enrolid');
     $mform->setType('enrolid', PARAM_INT);
     $data = array('id' => $course->id);
     if ($instance) {
         $data['link'] = $instance->customint1;
         $data['enrolid'] = $instance->id;
         $data['customint2'] = $instance->customint2;
         $mform->freeze('link');
         $this->add_action_buttons();
     } else {
         $this->add_add_buttons();
     }
     $this->set_data($data);
 }