/** * Find the list of users and get a list with the ids of students and a list of non-students * @param type $context_course * @return array(array($studentIds), array($non_studentIds), array($activeids), array($user_records)) */ function blended_get_users_by_type($context_course) { // Get users with gradable roles global $CFG; $gradable_roles = $CFG->gradebookroles; $roles = explode(',', $gradable_roles); $students = array(); foreach ($roles as $roleid) { $users_in_role = get_role_users($roleid, $context_course); $ids = array_keys($users_in_role); $students = array_merge($students, $ids); $students = array_unique($students); } // get enrolled users $user_records = get_enrolled_users($context_course, '', 0, '*'); $users = array_keys($user_records); $non_students = array_diff($users, $students); // select active userids $activeids = array(); global $DB; list($select, $params) = $DB->get_in_or_equal($students); $select = "userid {$select}"; $select .= " AND courseid = ?"; $params[] = (int) $context_course->instanceid; $last_accesses = $DB->get_records_select('user_lastaccess', $select, $params); foreach ($last_accesses as $record) { $activeids[] = $record->userid; } return array($students, $non_students, $activeids, $user_records); }
function game_showusers($game) { global $CFG, $USER; $users = array(); $context = get_context_instance(CONTEXT_COURSE, $game->course); if ($courseusers = get_enrolled_users($context)) { foreach ($courseusers as $courseuser) { $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context)); } } if ($guest = guest_user()) { $users[$guest->id] = fullname($guest); } ?> <script type="text/javascript"> function onselectuser() { window.location.href = "<?php echo $CFG->wwwroot . '/mod/game/showanswers.php?q=' . $game->id . '&userid='; ?> " + document.getElementById('menuuser').value; } </script> <?php //choose_from_menu($users, 'user', $USER->id, get_string("allparticipants"), 'javascript:onselectuser();'); //function choose_from_menu ($options, $name, $selected='', $nothing='choose', $script='', // $nothingvalue='0', $return=false, $disabled=false, $tabindex=0, // $id='', $listbox=false, $multiple=false, $class='') $attributes = 'onchange="javascript:onselectuser();"'; $name = 'user'; $id = 'menu' . $name; $class = 'menu' . $name; $class = 'select ' . $class; /// Add 'select' selector always $nothing = get_string("allparticipants"); $nothingvalue = '0'; $options = $users; $selected = optional_param('userid', $USER->id, PARAM_INT); $output = '<select id="' . $id . '" class="' . $class . '" name="' . $name . '" ' . $attributes . '>' . "\n"; $output .= ' <option value="' . s($nothingvalue) . '"' . "\n"; if ($nothingvalue === $selected) { $output .= ' selected="selected"'; } $output .= '>' . $nothing . '</option>' . "\n"; if (!empty($options)) { foreach ($options as $value => $label) { $output .= ' <option value="' . s($value) . '"'; if ((string) $value == (string) $selected || is_array($selected) && in_array($value, $selected)) { $output .= ' selected="selected"'; } if ($label === '') { $output .= '>' . $value . '</option>' . "\n"; } else { $output .= '>' . $label . '</option>' . "\n"; } } } echo $output . '</select>' . "\n"; }
/** * Constructor. * * @param string $uniqueid Unique ID. * @param int $courseid Course ID. * @param int $groupid Group ID. */ public function __construct($uniqueid, $courseid, $groupid) { global $DB, $PAGE; parent::__construct($uniqueid); // Block XP stuff. $this->xpmanager = block_xp_manager::get($courseid); $this->xpoutput = $PAGE->get_renderer('block_xp'); $context = context_course::instance($courseid); // Define columns. $this->define_columns(array('userpic', 'fullname', 'lvl', 'xp', 'progress', 'actions')); $this->define_headers(array('', get_string('fullname'), get_string('level', 'block_xp'), get_string('xp', 'block_xp'), get_string('progress', 'block_xp'), '')); // Get all the users that are enrolled and can earn XP. $ids = array(); $users = get_enrolled_users($context, 'block/xp:earnxp', $groupid); foreach ($users as $user) { $ids[$user->id] = $user->id; } unset($users); // Get the users which might not be enrolled or are revoked the permission, but still should // be displayed in the report for the teachers' benefit. We need to filter out the users which // are not a member of the group though. if (empty($groupid)) { $sql = 'SELECT userid FROM {block_xp} WHERE courseid = :courseid'; $params = array('courseid' => $courseid); } else { $sql = 'SELECT b.userid FROM {block_xp} b JOIN {groups_members} gm ON b.userid = gm.userid AND gm.groupid = :groupid WHERE courseid = :courseid'; $params = array('courseid' => $courseid, 'groupid' => $groupid); } $entries = $DB->get_recordset_sql($sql, $params); foreach ($entries as $entry) { $ids[$entry->userid] = $entry->userid; } $entries->close(); list($insql, $inparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED, 'param', true, null); // Define SQL. $this->sql = new stdClass(); $this->sql->fields = user_picture::fields('u') . ', COALESCE(x.lvl, 1) AS lvl, x.xp, ' . context_helper::get_preload_record_columns_sql('ctx'); $this->sql->from = "{user} u\n JOIN {context} ctx\n ON ctx.instanceid = u.id\n AND ctx.contextlevel = :contextlevel\n LEFT JOIN {block_xp} x\n ON (x.userid = u.id AND x.courseid = :courseid)"; $this->sql->where = "u.id {$insql}"; $this->sql->params = array_merge($inparams, array('courseid' => $courseid, 'contextlevel' => CONTEXT_USER)); // Define various table settings. $this->sortable(true, 'lvl', SORT_DESC); $this->no_sorting('userpic'); $this->no_sorting('progress'); $this->collapsible(false); }
/** * Defines forms elements */ public function definition() { global $COURSE, $DB, $CFG; $criteria = $this->_customdata['criteria']; $context = $this->_customdata['context']; $cmid = $this->_customdata['id']; $emarking = $this->_customdata['emarking']; $action = $this->_customdata['action']; $totalpages = $this->_customdata['totalpages']; $mform = $this->_form; // Add header. $mform->addElement('header', 'general', $action === 'addmarkers' ? get_string('assignmarkerstocriteria', 'mod_emarking') : get_string('assignpagestocriteria', 'mod_emarking')); // Hide course module id. $mform->addElement('hidden', 'id', $cmid); $mform->setType('id', PARAM_INT); // Hide action. $mform->addElement('hidden', 'action', $action); $mform->setType('action', PARAM_ALPHA); $mform->addElement('html', '<table class="addmarkerstable"><tr><td>'); if ($action === "addmarkers") { // Array of motives for regrading. $markers = get_enrolled_users($context, 'mod/assign:grade'); $chkmarkers = array(); foreach ($markers as $marker) { $chkmarkers[$marker->id] = $marker->firstname . " " . $marker->lastname; } $select = $mform->addElement('select', 'datamarkers', get_string('markers', 'mod_emarking'), $chkmarkers, null); $select->setMultiple(true); } else { $chkpages = array(); for ($i = 1; $i <= $totalpages; $i++) { $chkpages[$i] = get_string('page', 'mod_emarking') . " " . $i; } $select = $mform->addElement('select', 'datapages', core_text::strtotitle(get_string('pages', 'mod_emarking')), $chkpages, null); $select->setMultiple(true); } $criteriaitems = array(); foreach ($criteria as $criterion) { $criteriaitems[$criterion['id']] = $criterion['description']; } $mform->addElement('html', '</td><td>'); if ($action === "addmarkers") { $select = $mform->addElement('select', 'criteriamarkers', get_string('criteria', 'mod_emarking'), $criteriaitems, null); } else { $select = $mform->addElement('select', 'criteriapages', get_string('criteria', 'mod_emarking'), $criteriaitems, null); } $select->setMultiple(true); $mform->addElement('html', '</td></tr></table>'); // Add action buttons. $this->add_action_buttons(); }
function definition() { $courseid = optional_param('courseid', 0, PARAM_INT); $mform =& $this->_form; $context = context_course::instance($courseid); $mform->addElement('hidden', 'courseid', $courseid); $mform->setType('courseid', PARAM_INT); $users = get_enrolled_users($context); foreach ($users as $user) { $mform->addElement('advcheckbox', 'usersids[]', $user->firstname . ' ' . $user->lastname, ' email: ' . $user->email, array('group' => 1), array(0, $user->id)); //$mform->setDefault('usersids', $user->id); } $buttons = array(); $buttons[] =& $mform->createElement('submit', 'send', get_string('email_send', 'block_configurable_reports')); $buttons[] =& $mform->createElement('cancel'); $mform->addGroup($buttons, 'buttons', get_string('actions'), array(' '), false); }
/** * Defines forms elements */ public function definition() { global $COURSE, $DB, $CFG; $criteria = $this->_customdata['criteria']; $context = $this->_customdata['context']; $cmid = $this->_customdata['id']; $emarking = $this->_customdata['emarking']; $mform = $this->_form; // Add header $mform->addElement('header', 'general', get_string('assignmarkerstocriteria', 'mod_emarking')); // Hide course module id $mform->addElement('hidden', 'id', $cmid); $mform->setType('id', PARAM_INT); // Array of motives for regrading $markers = get_enrolled_users($context, 'mod/assign:grade'); foreach ($criteria as $criterion) { $chkmarkers = array(); foreach ($markers as $marker) { $chkmarkers[] = $mform->createElement('checkbox', 'assign-' . $criterion['id'] . '-' . $marker->id, null, $marker->firstname . " " . $marker->lastname); } // Add markers group as checkboxes $mform->addGroup($chkmarkers, 'markers-' . $criterion['id'], $criterion['description'], array('<br />'), false); $mform->addRule('markers-' . $criterion['id'], get_string('required'), 'required', null, 'client'); $mform->setType('markers-' . $criterion['id'], PARAM_INT); } if (isset($emarking->totalpages) && $emarking->totalpages > 0) { // Add header $mform->addElement('header', 'general', ucfirst(get_string('assignpagestocriteria', 'mod_emarking'))); foreach ($criteria as $criterion) { $chkpages = array(); for ($i = 1; $i <= $emarking->totalpages; $i++) { $chkpages[] = $mform->createElement('checkbox', 'page-' . $criterion['id'] . '-' . $i, null, get_string('page', 'mod_emarking') . " " . $i); } // Add pages group as checkboxes $mform->addGroup($chkpages, 'pages-' . $criterion['id'], $criterion['description'], array('<br />'), false); $mform->addRule('pages-' . $criterion['id'], get_string('required'), 'required', null, 'client'); $mform->setType('pages-' . $criterion['id'], PARAM_INT); } } // Add action buttons $this->add_action_buttons(); }
function block_print_user_table($blockid, $courseid, $skillmax, $return = false) { $context = context_course::instance($courseid); $userfields = 'u.id, u.firstname, u.lastname'; $userlist = get_enrolled_users($context, 'block/skill_bars:viewpages', 0, $userfields); $skillslist = get_course_skills($courseid); $headers = array('User'); foreach ($skillslist as $skill) { $headers[] = $skill->name; } $showlist = new html_table(); $showlist->head = $headers; $showlistdata = array(); foreach ($userlist as $user) { $fullname = $user->firstname . " " . $user->lastname; $skills = get_user_skills($user->id, $courseid); $record = array(); if (count($skills)) { $url = new moodle_url('/blocks/skill_bars/update.php', array('blockid' => $blockid, 'courseid' => $courseid, 'userid' => $user->id)); $link = html_writer::link($url, $fullname); $record[] = $link; foreach ($skills as $skill) { $record[] = get_skillbar_icon($skill->points, $skillmax); } } else { $record[] = $fullname; foreach ($skillslist as $skill) { $record[] = ''; } } $showlistdata[] = $record; } $showlist->data = $showlistdata; if ($return) { return html_writer::table($showlist); } else { echo html_writer::table($showlist); } }
public function definition() { global $COURSE; $context = context_course::instance($COURSE->id); $namefields = get_all_user_name_fields(true, 'u'); $students = get_enrolled_users($context, 'mod/attendance:canbelisted', 0, 'u.id,' . $namefields . ',u.email', 'u.lastname, u.firstname', 0, 0, true); $partarray = array(); foreach ($students as $student) { $partarray[$student->id] = fullname($student) . ' (' . $student->email . ')'; } $mform = $this->_form; $description = $this->_customdata['description']; $mform->addElement('hidden', 'id', 0); $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'userid', 0); $mform->setType('userid', PARAM_INT); $mform->addElement('header', 'attheader', get_string('tempusermerge', 'attendance')); $mform->addElement('static', 'description', get_string('tempuser', 'attendance'), $description); $mform->addElement('select', 'participant', get_string('participant', 'attendance'), $partarray); $mform->addElement('static', 'requiredentries', '', get_string('requiredentries', 'attendance')); $mform->addHelpButton('requiredentries', 'requiredentry', 'attendance'); $this->add_action_buttons(true, get_string('mergeuser', 'attendance')); }
/** * Constructor. * * @param string $uniqueid Unique ID. */ public function __construct($uniqueid, $courseid) { global $DB, $PAGE; parent::__construct($uniqueid); // Block XP stuff. $this->xpmanager = block_xp_manager::get($courseid); $this->xpoutput = $PAGE->get_renderer('block_xp'); $context = context_course::instance($courseid); // Define columns. $this->define_columns(array('userpic', 'fullname', 'lvl', 'xp', 'progress', 'actions')); $this->define_headers(array('', get_string('fullname'), get_string('level', 'block_xp'), get_string('xp', 'block_xp'), get_string('progress', 'block_xp'), '')); // Get the relevant user IDs, users enrolled or users with XP. // This might be a performance issue at some point. $ids = array(); $users = get_enrolled_users($context, 'block/xp:earnxp'); foreach ($users as $user) { $ids[$user->id] = $user->id; } unset($users); $entries = $DB->get_recordset_sql('SELECT userid FROM {block_xp} WHERE courseid = :courseid', array('courseid' => $courseid)); foreach ($entries as $entry) { $ids[$entry->userid] = $entry->userid; } $entries->close(); list($insql, $inparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED, 'param', true, null); // Define SQL. $this->sql = new stdClass(); $this->sql->fields = user_picture::fields('u') . ', x.lvl, x.xp'; $this->sql->from = "{user} u LEFT JOIN {block_xp} x ON (x.userid = u.id AND x.courseid = :courseid)"; $this->sql->where = "u.id {$insql}"; $this->sql->params = array_merge($inparams, array('courseid' => $courseid)); // Define various table settings. $this->sortable(true, 'lvl', SORT_DESC); $this->no_sorting('userpic'); $this->no_sorting('progress'); $this->collapsible(false); }
function get_content() { global $CFG, $OUTPUT; if ($this->content !== null) { return $this->content; } $this->content = new stdClass(); $this->content->footer = ''; if (empty($this->instance)) { $this->content->text = ''; return $this->content; } // user/index.php expect course context, so get one if page has module context. $currentcontext = $this->page->context->get_course_context(false); if (!empty($this->config->text)) { $this->content->text = $this->config->text; } $this->content->text = 'No Hangout'; if (empty($currentcontext)) { return $this->content; } if ($this->page->course->id == SITEID) { $this->context->text .= "site context"; } $users = get_enrolled_users($currentcontext); $usersemails = ''; foreach ($users as $user) { $usersemails .= "{ id : '{$user->email}', invite_type : 'EMAIL' },"; } $this->content->text = "<script src=\"https://apis.google.com/js/platform.js\" async defer></script>\n <g:hangout render=\"createhangout\" invites=\"[{$usersemails}]\"></g:hangout>"; $this->content->text .= '<br><a href= "' . $CFG->wwwroot . '/blocks/google_hangout/select_users.php?courseid=' . $this->page->course->id . '" alt="Select users">Hangout with selected users</a>'; if (!empty($this->config->text)) { $this->content->text .= $this->config->text; } return $this->content; }
/** * Show a form with a dropdown box to allow tutors who are enrolled in Moodle * on this course to be added to this course in Turnitin * * @global type $CFG * @global type $OUTPUT * @param obj $cm course module data * @param array $tutors tutors who are currently enrolled with Turnitin * @return output */ public function show_add_tii_tutors_form($cm, $tutors) { global $CFG, $OUTPUT; $moodletutors = get_enrolled_users(context_module::instance($cm->id), 'mod/turnitintooltwo:grade', 0, 'u.id'); // Populate elements array which will generate the form elements // Each element is in following format: (type, name, label, helptext (minus _help), options (if select). $elements = array(); $elements[] = array('header', 'add_tii_tutors', get_string('turnitintutorsadd', 'turnitintooltwo')); $options = array(); foreach ($moodletutors as $k => $v) { $availabletutor = new turnitintooltwo_user($v->id, "Instructor", false, "site", false); if (array_key_exists($availabletutor->id, $tutors)) { unset($moodletutors[$k]); } else { $options[$availabletutor->id] = $availabletutor->fullname . ' (' . $availabletutor->email . ')'; } } if (count($options) == 0) { $elements[] = array('static', 'turnitintutors', get_string('turnitintutors', 'turnitintooltwo') . ": ", '', get_string('turnitintutorsallenrolled', 'turnitintooltwo')); $customdata["hide_submit"] = true; } else { $elements[] = array('select', 'turnitintutors', get_string('turnitintutors', 'turnitintooltwo'), '', $options); $elements[] = array('hidden', 'action', 'addtutor'); $customdata["show_cancel"] = false; $customdata["submit_label"] = get_string('turnitintutorsadd', 'turnitintooltwo'); } $customdata["elements"] = $elements; $form = new turnitintooltwo_form($CFG->wwwroot . '/mod/turnitintooltwo/view.php' . '?id=' . $cm->id . '&do=tutors', $customdata); $output = $OUTPUT->box($form->display(), 'generalbox boxaligncenter', 'general'); return $output; }
/** * Returns submissions by part (and unsubmitted users if appropriate) * * @global type $DB * @global type $USER * @param object $cm course module object * @param int $partid specific part id, includes all if 0 * @param int $userid specific user id, includes all if 0 * @param int $submissionsonly flag to include/remove non submitted students from results * @return array of submissions by part */ public function get_submissions($cm, $partid = 0, $userid = 0, $submissionsonly = 0) { global $DB, $USER; // If no part id is specified then get them all. $sql = " turnitintooltwoid = ? "; $sqlparams = array($this->id); if ($partid == 0) { $parts = $this->get_parts(); } else { $part = $this->get_part_details($partid); $parts[$partid] = $part; $sql .= " AND submission_part = ? "; $sqlparams[] = $partid; } $context = context_module::instance($cm->id); $istutor = has_capability('mod/turnitintooltwo:grade', $context); // If logged in as instructor then get for all users. $allnamefields = get_all_user_name_fields(); if ($istutor && $userid == 0) { $users = get_enrolled_users($context, 'mod/turnitintooltwo:submit', groups_get_activity_group($cm), 'u.id, ' . implode($allnamefields, ', ')); $users = !$users ? array() : $users; } else { if ($istutor) { $user = $DB->get_record('user', array('id' => $userid), 'id, ' . implode($allnamefields, ', ')); $users = array($userid => $user); $sql .= " AND userid = ? "; $sqlparams[] = $userid; } else { $users = array($USER->id => $USER); $sql .= " AND userid = ? "; $sqlparams[] = $USER->id; } } // Populate the submissions array to show all users for all parts. $submissions = array(); foreach ($parts as $part) { $submissions[$part->id] = array(); foreach ($users as $user) { $emptysubmission = new stdClass(); $emptysubmission->userid = $user->id; $emptysubmission->firstname = $user->firstname; $emptysubmission->lastname = $user->lastname; $emptysubmission->fullname = fullname($user); $emptysubmission->submission_unanon = 0; $emptysubmission->nmoodle = 0; if ($submissionsonly == 0) { $submissions[$part->id][$user->id] = $emptysubmission; } } } // Get submissions that were made where a moodle userid is known. // Contains moodle users both enrolled or not enrolled. if ($submissionsdata = $DB->get_records_select("turnitintooltwo_submissions", " userid != 0 AND " . $sql, $sqlparams)) { foreach ($submissionsdata as $submission) { $user = new turnitintooltwo_user($submission->userid, 'Learner', false); $submission->firstname = $user->firstname; $submission->lastname = $user->lastname; $submission->fullname = $user->fullname; $submission->tii_user_id = $user->tii_user_id; $submission->nmoodle = 0; if (isset($users[$user->id])) { // User is a moodle user ie in array from moodle user call above. $submissions[$submission->submission_part][$user->id] = $submission; } else { if (groups_get_activity_group($cm) == 0) { // User is not a moodle user ie not in array from moodle user call above and group list is set to all users. $submission->nmoodle = 1; $submissions[$submission->submission_part][$user->id] = $submission; } } } } // Now get submissions that were made by a non moodle students. // These are unknown to moodle possibly non-enrolled on turnitin. // Possibly real but not yet linked Turnitin users. If group list is set do not get these non group users. if ($submissionsdata = $DB->get_records_select("turnitintooltwo_submissions", " userid = 0 AND " . $sql, $sqlparams) and groups_get_activity_group($cm) == 0) { foreach ($submissionsdata as $submission) { $submission->nmoodle = 1; $submission->userid = $submission->submission_nmuserid; $submission->firstname = $submission->submission_nmfirstname; $submission->lastname = $submission->submission_nmlastname; $submissions[$submission->submission_part][$submission->userid] = $submission; } } return $submissions; }
function definition() { global $CFG, $COURSE, $USER; $mform =& $this->_form; $context = context_course::instance($COURSE->id); $modinfo = get_fast_modinfo($COURSE); $sections = get_all_sections($COURSE->id); $mform->addElement('header', 'filters', get_string('managefilters')); //TODO: add better string $groupoptions = array(); if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { // limited group access $groups = groups_get_user_groups($COURSE->id); $allgroups = groups_get_all_groups($COURSE->id); if (!empty($groups[$COURSE->defaultgroupingid])) { foreach ($groups[$COURSE->defaultgroupingid] as $groupid) { $groupoptions[$groupid] = format_string($allgroups[$groupid]->name, true, array('context' => $context)); } } } else { $groupoptions = array('0' => get_string('allgroups')); if (has_capability('moodle/site:accessallgroups', $context)) { // user can see all groups $allgroups = groups_get_all_groups($COURSE->id); } else { // user can see course level groups $allgroups = groups_get_all_groups($COURSE->id, 0, $COURSE->defaultgroupingid); } foreach ($allgroups as $group) { $groupoptions[$group->id] = format_string($group->name, true, array('context' => $context)); } } if ($COURSE->id == SITEID) { $viewparticipants = has_capability('moodle/site:viewparticipants', context_system::instance()); } else { $viewparticipants = has_capability('moodle/course:viewparticipants', $context); } if ($viewparticipants) { $viewfullnames = has_capability('moodle/site:viewfullnames', context_course::instance($COURSE->id)); $options = array(); $options[0] = get_string('allparticipants'); $options[$CFG->siteguest] = get_string('guestuser'); if (isset($groupoptions[0])) { // can see all enrolled users if ($enrolled = get_enrolled_users($context, null, 0, user_picture::fields('u'))) { foreach ($enrolled as $euser) { $options[$euser->id] = fullname($euser, $viewfullnames); } } } else { // can see users from some groups only foreach ($groupoptions as $groupid => $unused) { if ($enrolled = get_enrolled_users($context, null, $groupid, user_picture::fields('u'))) { foreach ($enrolled as $euser) { if (!array_key_exists($euser->id, $options)) { $options[$euser->id] = fullname($euser, $viewfullnames); } } } } } $mform->addElement('select', 'user', get_string('participants'), $options); $mform->setAdvanced('user'); } $sectiontitle = get_string('sectionname', 'format_' . $COURSE->format); $options = array('' => get_string('allactivities')); $modsused = array(); foreach ($modinfo->cms as $cm) { if (!$cm->uservisible) { continue; } $modsused[$cm->modname] = true; } foreach ($modsused as $modname => $unused) { $libfile = "{$CFG->dirroot}/mod/{$modname}/lib.php"; if (!file_exists($libfile)) { unset($modsused[$modname]); continue; } include_once $libfile; $libfunction = $modname . "_get_recent_mod_activity"; if (!function_exists($libfunction)) { unset($modsused[$modname]); continue; } $options["mod/{$modname}"] = get_string('allmods', '', get_string('modulenameplural', $modname)); } foreach ($modinfo->sections as $section => $cmids) { $options["section/{$section}"] = "-- " . get_section_name($COURSE, $sections[$section]) . " --"; foreach ($cmids as $cmid) { $cm = $modinfo->cms[$cmid]; if (empty($modsused[$cm->modname]) or !$cm->uservisible) { continue; } $options[$cm->id] = format_string($cm->name); } } $mform->addElement('select', 'modid', get_string('activities'), $options); $mform->setAdvanced('modid'); if ($groupoptions) { $mform->addElement('select', 'group', get_string('groups'), $groupoptions); $mform->setAdvanced('group'); } else { // no access to groups in separate mode $mform->addElement('hidden', 'group'); $mform->setType('group', PARAM_INT); $mform->setConstants(array('group' => -1)); } $options = array('default' => get_string('bycourseorder'), 'dateasc' => get_string('datemostrecentlast'), 'datedesc' => get_string('datemostrecentfirst')); $mform->addElement('select', 'sortby', get_string('sortby'), $options); $mform->setAdvanced('sortby'); $mform->addElement('date_time_selector', 'date', get_string('since'), array('optional' => true)); $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $mform->setType('courseid', PARAM_INT); $this->add_action_buttons(false, get_string('showrecent')); }
/** * Display a single submission, ready for grading on a popup window * * This default method prints the teacher info and submissioncomment box at the top and * the student info and submission at the bottom. * This method also fetches the necessary data in order to be able to * provide a "Next submission" button. * Calls preprocess_submission() to give assignment type plug-ins a chance * to process submissions before they are graded * This method gets its arguments from the page parameters userid and offset * * @global object * @global object * @param string $extra_javascript */ function display_submission($offset=-1,$userid =-1, $display=true) { global $CFG, $DB, $PAGE, $OUTPUT; require_once($CFG->libdir.'/gradelib.php'); require_once($CFG->libdir.'/tablelib.php'); require_once("$CFG->dirroot/repository/lib.php"); if ($userid==-1) { $userid = required_param('userid', PARAM_INT); } if ($offset==-1) { $offset = required_param('offset', PARAM_INT);//offset for where to start looking for student. } $filter = optional_param('filter', 0, PARAM_INT); if (!$user = $DB->get_record('user', array('id'=>$userid))) { print_error('nousers'); } if (!$submission = $this->get_submission($user->id)) { $submission = $this->prepare_new_submission($userid); } if ($submission->timemodified > $submission->timemarked) { $subtype = 'assignmentnew'; } else { $subtype = 'assignmentold'; } $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array($user->id)); $gradingdisabled = $grading_info->items[0]->grades[$userid]->locked || $grading_info->items[0]->grades[$userid]->overridden; /// construct SQL, using current offset to find the data of the next student $course = $this->course; $assignment = $this->assignment; $cm = $this->cm; $context = get_context_instance(CONTEXT_MODULE, $cm->id); /// Get all ppl that can submit assignments $currentgroup = groups_get_activity_group($cm); $users = get_enrolled_users($context, 'mod/assignment:view', $currentgroup, 'u.id'); if ($users) { $users = array_keys($users); // if groupmembersonly used, remove users who are not in any group if (!empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { $users = array_intersect($users, array_keys($groupingusers)); } } } $nextid = 0; $where = ''; if($filter == 'submitted') { $where .= 's.timemodified > 0 AND '; } else if($filter == 'requiregrading') { $where .= 's.timemarked < s.timemodified AND '; } if ($users) { $userfields = user_picture::fields('u', array('lastaccess')); $select = "SELECT $userfields, s.id AS submissionid, s.grade, s.submissioncomment, s.timemodified, s.timemarked, COALESCE(SIGN(SIGN(s.timemarked) + SIGN(s.timemarked - s.timemodified)), 0) AS status "; $sql = 'FROM {user} u '. 'LEFT JOIN {assignment_submissions} s ON u.id = s.userid AND s.assignment = '.$this->assignment->id.' '. 'WHERE '.$where.'u.id IN ('.implode(',', $users).') '; if ($sort = flexible_table::get_sort_for_table('mod-assignment-submissions')) { $sort = 'ORDER BY '.$sort.' '; } $auser = $DB->get_records_sql($select.$sql.$sort, null, $offset, 2); if (is_array($auser) && count($auser)>1) { $nextuser = next($auser); /// Calculate user status $nextuser->status = ($nextuser->timemarked > 0) && ($nextuser->timemarked >= $nextuser->timemodified); $nextid = $nextuser->id; } } if ($submission->teacher) { $teacher = $DB->get_record('user', array('id'=>$submission->teacher)); } else { global $USER; $teacher = $USER; } $this->preprocess_submission($submission); $mformdata = new stdClass(); $mformdata->context = $this->context; $mformdata->maxbytes = $this->course->maxbytes; $mformdata->courseid = $this->course->id; $mformdata->teacher = $teacher; $mformdata->assignment = $assignment; $mformdata->submission = $submission; $mformdata->lateness = $this->display_lateness($submission->timemodified); $mformdata->auser = $auser; $mformdata->user = $user; $mformdata->offset = $offset; $mformdata->userid = $userid; $mformdata->cm = $this->cm; $mformdata->grading_info = $grading_info; $mformdata->enableoutcomes = $CFG->enableoutcomes; $mformdata->grade = $this->assignment->grade; $mformdata->gradingdisabled = $gradingdisabled; $mformdata->nextid = $nextid; $mformdata->submissioncomment= $submission->submissioncomment; $mformdata->submissioncommentformat= FORMAT_HTML; $mformdata->submission_content= $this->print_user_files($user->id,true); $mformdata->filter = $filter; if ($assignment->assignmenttype == 'upload') { $mformdata->fileui_options = array('subdirs'=>1, 'maxbytes'=>$assignment->maxbytes, 'maxfiles'=>$assignment->var1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL); } elseif ($assignment->assignmenttype == 'uploadsingle') { $mformdata->fileui_options = array('subdirs'=>0, 'maxbytes'=>$CFG->userquota, 'maxfiles'=>1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL); } $submitform = new mod_assignment_grading_form( null, $mformdata ); if (!$display) { $ret_data = new stdClass(); $ret_data->mform = $submitform; $ret_data->fileui_options = $mformdata->fileui_options; return $ret_data; } if ($submitform->is_cancelled()) { redirect('submissions.php?id='.$this->cm->id); } $submitform->set_data($mformdata); $PAGE->set_title($this->course->fullname . ': ' .get_string('feedback', 'assignment').' - '.fullname($user, true)); $PAGE->set_heading($this->course->fullname); $PAGE->navbar->add(get_string('submissions', 'assignment'), new moodle_url('/mod/assignment/submissions.php', array('id'=>$cm->id))); $PAGE->navbar->add(fullname($user, true)); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('feedback', 'assignment').': '.fullname($user, true)); // display mform here... $submitform->display(); $customfeedback = $this->custom_feedbackform($submission, true); if (!empty($customfeedback)) { echo $customfeedback; } echo $OUTPUT->footer(); }
/** * Print an overview of all assignments * for the courses. * * @param mixed $courses The list of courses to print the overview for * @param array $htmlarray The array of html to return */ function assign_print_overview($courses, &$htmlarray) { global $USER, $CFG, $DB; if (empty($courses) || !is_array($courses) || count($courses) == 0) { return array(); } if (!($assignments = get_all_instances_in_courses('assign', $courses))) { return; } $assignmentids = array(); // Do assignment_base::isopen() here without loading the whole thing for speed foreach ($assignments as $key => $assignment) { $time = time(); $isopen = false; if ($assignment->duedate) { $duedate = false; if ($assignment->cutoffdate) { $duedate = $assignment->cutoffdate; } if ($duedate) { $isopen = $assignment->allowsubmissionsfromdate <= $time && $time <= $duedate; } else { $isopen = $assignment->allowsubmissionsfromdate <= $time; } } if ($isopen) { $assignmentids[] = $assignment->id; } } if (empty($assignmentids)) { // no assignments to look at - we're done return true; } $strduedate = get_string('duedate', 'assign'); $strcutoffdate = get_string('nosubmissionsacceptedafter', 'assign'); $strnolatesubmissions = get_string('nolatesubmissions', 'assign'); $strduedateno = get_string('duedateno', 'assign'); $strduedateno = get_string('duedateno', 'assign'); $strgraded = get_string('graded', 'assign'); $strnotgradedyet = get_string('notgradedyet', 'assign'); $strnotsubmittedyet = get_string('notsubmittedyet', 'assign'); $strsubmitted = get_string('submitted', 'assign'); $strassignment = get_string('modulename', 'assign'); $strreviewed = get_string('reviewed', 'assign'); // NOTE: we do all possible database work here *outside* of the loop to ensure this scales // list($sqlassignmentids, $assignmentidparams) = $DB->get_in_or_equal($assignmentids); // build up and array of unmarked submissions indexed by assignment id/ userid // for use where the user has grading rights on assignment $rs = $DB->get_recordset_sql("SELECT s.assignment as assignment, s.userid as userid, s.id as id, s.status as status, g.timemodified as timegraded\n FROM {assign_submission} s LEFT JOIN {assign_grades} g ON s.userid = g.userid and s.assignment = g.assignment\n WHERE g.timemodified = 0 OR s.timemodified > g.timemodified\n AND s.assignment {$sqlassignmentids}", $assignmentidparams); $unmarkedsubmissions = array(); foreach ($rs as $rd) { $unmarkedsubmissions[$rd->assignment][$rd->userid] = $rd->id; } $rs->close(); // get all user submissions, indexed by assignment id $mysubmissions = $DB->get_records_sql("SELECT a.id AS assignment, a.nosubmissions AS nosubmissions, g.timemodified AS timemarked, g.grader AS grader, g.grade AS grade, s.status AS status\n FROM {assign} a LEFT JOIN {assign_grades} g ON g.assignment = a.id AND g.userid = ? LEFT JOIN {assign_submission} s ON s.assignment = a.id AND s.userid = ?\n AND a.id {$sqlassignmentids}", array_merge(array($USER->id, $USER->id), $assignmentidparams)); foreach ($assignments as $assignment) { // Do not show assignments that are not open if (!in_array($assignment->id, $assignmentids)) { continue; } $str = '<div class="assign overview"><div class="name">' . $strassignment . ': ' . '<a ' . ($assignment->visible ? '' : ' class="dimmed"') . 'title="' . $strassignment . '" href="' . $CFG->wwwroot . '/mod/assign/view.php?id=' . $assignment->coursemodule . '">' . format_string($assignment->name) . '</a></div>'; if ($assignment->duedate) { $str .= '<div class="info">' . $strduedate . ': ' . userdate($assignment->duedate) . '</div>'; } else { $str .= '<div class="info">' . $strduedateno . '</div>'; } if ($assignment->cutoffdate) { if ($assignment->cutoffdate == $assignment->duedate) { $str .= '<div class="info">' . $strnolatesubmissions . '</div>'; } else { $str .= '<div class="info">' . $strcutoffdate . ': ' . userdate($assignment->cutoffdate) . '</div>'; } } $context = context_module::instance($assignment->coursemodule); if (has_capability('mod/assign:grade', $context)) { // count how many people can submit $submissions = 0; // init if ($students = get_enrolled_users($context, 'mod/assign:view', 0, 'u.id')) { foreach ($students as $student) { if (isset($unmarkedsubmissions[$assignment->id][$student->id])) { $submissions++; } } } if ($submissions) { $link = new moodle_url('/mod/assign/view.php', array('id' => $assignment->coursemodule, 'action' => 'grading')); $str .= '<div class="details"><a href="' . $link . '">' . get_string('submissionsnotgraded', 'assign', $submissions) . '</a></div>'; } } if (has_capability('mod/assign:submit', $context)) { $str .= '<div class="details">'; $str .= get_string('mysubmission', 'assign'); $submission = $mysubmissions[$assignment->id]; if ($submission->nosubmissions) { $str .= get_string('offline', 'assign'); } else { if (!$submission->status || $submission->status == 'draft') { $str .= $strnotsubmittedyet; } else { $str .= get_string('submissionstatus_' . $submission->status, 'assign'); } } if (!$submission->grade || $submission->grade < 0) { $str .= ', ' . get_string('notgraded', 'assign'); } else { $str .= ', ' . get_string('graded', 'assign'); } $str .= '</div>'; } $str .= '</div>'; if (empty($htmlarray[$assignment->course]['assign'])) { $htmlarray[$assignment->course]['assign'] = $str; } else { $htmlarray[$assignment->course]['assign'] .= $str; } } }
/** * Testing the reset on groups, group members and enrolments. */ public function test_reset() { global $DB; $this->resetAfterTest(true); $c1 = $this->getDataGenerator()->create_course(); $c1ctx = context_course::instance($c1->id); $studentrole = $DB->get_record('role', array('shortname' => 'student')); $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); $u1 = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($u1->id, $c1->id, $studentrole->id); $this->assertCount(1, get_enrolled_users($c1ctx)); $g1 = $this->getDataGenerator()->create_group(array('courseid' => $c1->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $g1->id, 'userid' => $u1->id)); $this->assertEquals(1, $DB->count_records('groups', array('courseid' => $c1->id))); $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); // Wrong mode. $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => 'DoesNotExist', 'reset' => '1', 'summary' => 'summary', 'fullname' => 'FN', 'category' => 1); $co = new tool_uploadcourse_course($mode, $updatemode, $data); $this->assertFalse($co->prepare()); $this->assertArrayHasKey('canonlyresetcourseinupdatemode', $co->get_errors()); $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); $this->assertCount(1, get_enrolled_users($c1ctx)); // Reset not allowed. $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => $c1->shortname, 'reset' => '1'); $importoptions = array('canreset' => false); $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); $this->assertFalse($co->prepare()); $this->assertArrayHasKey('courseresetnotallowed', $co->get_errors()); $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); $this->assertCount(1, get_enrolled_users($c1ctx)); // Reset allowed but not requested. $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => $c1->shortname, 'reset' => '0'); $importoptions = array('canreset' => true); $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); $this->assertTrue($co->prepare()); $co->proceed(); $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); $this->assertCount(1, get_enrolled_users($c1ctx)); // Reset passed as a default parameter, should not be taken in account. $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => $c1->shortname); $importoptions = array('canreset' => true); $co = new tool_uploadcourse_course($mode, $updatemode, $data, array('reset' => 1), $importoptions); $this->assertTrue($co->prepare()); $co->proceed(); $this->assertTrue($DB->record_exists('groups', array('id' => $g1->id))); $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); $this->assertCount(1, get_enrolled_users($c1ctx)); // Reset executed from data. $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => $c1->shortname, 'reset' => 1); $importoptions = array('canreset' => true); $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); $this->assertTrue($co->prepare()); $co->proceed(); $this->assertFalse($DB->record_exists('groups', array('id' => $g1->id))); $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $g1->id, 'userid' => $u1->id))); $this->assertCount(0, get_enrolled_users($c1ctx)); // Reset executed from import option. $mode = tool_uploadcourse_processor::MODE_UPDATE_ONLY; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; $data = array('shortname' => $c1->shortname, 'reset' => 0); $importoptions = array('reset' => 1, 'canreset' => true); $co = new tool_uploadcourse_course($mode, $updatemode, $data, array(), $importoptions); $g1 = $this->getDataGenerator()->create_group(array('courseid' => $c1->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $g1->id, 'userid' => $u1->id)); $this->assertEquals(1, $DB->count_records('groups', array('courseid' => $c1->id))); $this->assertTrue($co->prepare()); $co->proceed(); $this->assertFalse($DB->record_exists('groups', array('id' => $g1->id))); }
/** * Called to define this moodle form * * @return void */ public function definition() { global $USER, $DB, $PAGE; $mform =& $this->_form; $course = $this->_customdata['course']; $cm = $this->_customdata['cm']; $modcontext = $this->_customdata['modcontext']; $mform->addElement('header', 'general', get_string('export', 'attendance')); $groupmode = groups_get_activity_groupmode($cm, $course); $groups = groups_get_activity_allowed_groups($cm, $USER->id); if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $modcontext)) { $grouplist[0] = get_string('allparticipants'); } if ($groups) { foreach ($groups as $group) { $grouplist[$group->id] = $group->name; } } $mform->addElement('select', 'group', get_string('group'), $grouplist); // Restrict the export to the selected users. $namefields = get_all_user_name_fields(true, 'u'); $allusers = get_enrolled_users($modcontext, 'mod/attendance:canbelisted', 0, 'u.id,' . $namefields); $userlist = array(); foreach ($allusers as $user) { $userlist[$user->id] = fullname($user); } unset($allusers); $tempusers = $DB->get_records('attendance_tempusers', array('courseid' => $course->id), 'studentid, fullname'); foreach ($tempusers as $user) { $userlist[$user->studentid] = $user->fullname; } list($gsql, $gparams) = $DB->get_in_or_equal(array_keys($grouplist), SQL_PARAMS_NAMED); list($usql, $uparams) = $DB->get_in_or_equal(array_keys($userlist), SQL_PARAMS_NAMED); $params = array_merge($gparams, $uparams); $groupmembers = $DB->get_recordset_select('groups_members', "groupid {$gsql} AND userid {$usql}", $params, '', 'groupid, userid'); $groupmappings = array(); foreach ($groupmembers as $groupmember) { if (!isset($groupmappings[$groupmember->groupid])) { $groupmappings[$groupmember->groupid] = array(); } $groupmappings[$groupmember->groupid][$groupmember->userid] = $userlist[$groupmember->userid]; } if (isset($grouplist[0])) { $groupmappings[0] = $userlist; } $mform->addElement('selectyesno', 'selectedusers', get_string('onlyselectedusers', 'mod_attendance')); $sel = $mform->addElement('select', 'users', get_string('users', 'mod_attendance'), $userlist, array('size' => 12)); $sel->setMultiple(true); $mform->disabledIf('users', 'selectedusers', 'eq', 0); $opts = array('groupmappings' => $groupmappings); $PAGE->requires->yui_module('moodle-mod_attendance-groupfilter', 'M.mod_attendance.groupfilter.init', array($opts)); $ident = array(); $ident[] =& $mform->createElement('checkbox', 'id', '', get_string('studentid', 'attendance')); $ident[] =& $mform->createElement('checkbox', 'uname', '', get_string('username')); $optional = array('idnumber', 'institution', 'department'); foreach ($optional as $opt) { $ident[] =& $mform->createElement('checkbox', $opt, '', get_string($opt)); $mform->setType($opt, PARAM_NOTAGS); } $mform->addGroup($ident, 'ident', get_string('identifyby', 'attendance'), array('<br />'), true); $mform->setDefaults(array('ident[id]' => true, 'ident[uname]' => true)); $mform->setType('id', PARAM_INT); $mform->setType('uname', PARAM_INT); $mform->addElement('checkbox', 'includeallsessions', get_string('includeall', 'attendance'), get_string('yes')); $mform->setDefault('includeallsessions', true); $mform->addElement('checkbox', 'includenottaken', get_string('includenottaken', 'attendance'), get_string('yes')); $mform->addElement('checkbox', 'includeremarks', get_string('includeremarks', 'attendance'), get_string('yes')); $mform->addElement('date_selector', 'sessionstartdate', get_string('startofperiod', 'attendance')); $mform->setDefault('sessionstartdate', $course->startdate); $mform->disabledIf('sessionstartdate', 'includeallsessions', 'checked'); $mform->addElement('date_selector', 'sessionenddate', get_string('endofperiod', 'attendance')); $mform->disabledIf('sessionenddate', 'includeallsessions', 'checked'); $mform->addElement('select', 'format', get_string('format'), array('excel' => get_string('downloadexcel', 'attendance'), 'ooo' => get_string('downloadooo', 'attendance'), 'text' => get_string('downloadtext', 'attendance'))); $submitstring = get_string('ok'); $this->add_action_buttons(false, $submitstring); $mform->addElement('hidden', 'id', $cm->id); }
/** * Display a single submission, ready for grading on a popup window * * This default method prints the teacher info and submissioncomment box at the top and * the student info and submission at the bottom. * This method also fetches the necessary data in order to be able to * provide a "Next submission" button. * Calls preprocess_submission() to give assignment type plug-ins a chance * to process submissions before they are graded * This method gets its arguments from the page parameters userid and offset * * @global object * @global object * @param string $extra_javascript */ function display_submission($offset = -1, $userid = -1, $display = true) { global $CFG, $DB, $PAGE, $OUTPUT, $USER; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->libdir . '/tablelib.php'; require_once "{$CFG->dirroot}/repository/lib.php"; require_once "{$CFG->dirroot}/grade/grading/lib.php"; if ($userid == -1) { $userid = required_param('userid', PARAM_INT); } if ($offset == -1) { $offset = required_param('offset', PARAM_INT); //offset for where to start looking for student. } $filter = optional_param('filter', 0, PARAM_INT); if (!($user = $DB->get_record('user', array('id' => $userid)))) { print_error('nousers'); } if (!($submission = $this->get_submission($user->id))) { $submission = $this->prepare_new_submission($userid); } if ($submission->timemodified > $submission->timemarked) { $subtype = 'assignmentnew'; } else { $subtype = 'assignmentold'; } $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array($user->id)); $gradingdisabled = $grading_info->items[0]->grades[$userid]->locked || $grading_info->items[0]->grades[$userid]->overridden; /// construct SQL, using current offset to find the data of the next student $course = $this->course; $assignment = $this->assignment; $cm = $this->cm; $context = context_module::instance($cm->id); //reset filter to all for offline assignment if ($assignment->assignmenttype == 'offline' && $filter == self::FILTER_SUBMITTED) { $filter = self::FILTER_ALL; } /// Get all ppl that can submit assignments $currentgroup = groups_get_activity_group($cm); $users = get_enrolled_users($context, 'mod/assignment:submit', $currentgroup, 'u.id'); if ($users) { $users = array_keys($users); // if groupmembersonly used, remove users who are not in any group if (!empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { $users = array_intersect($users, array_keys($groupingusers)); } } } $nextid = 0; $where = ''; if ($filter == self::FILTER_SUBMITTED) { $where .= 's.timemodified > 0 AND '; } else { if ($filter == self::FILTER_REQUIRE_GRADING) { $where .= 's.timemarked < s.timemodified AND '; } } if ($users) { $userfields = user_picture::fields('u', array('lastaccess')); $select = "SELECT {$userfields},\n s.id AS submissionid, s.grade, s.submissioncomment,\n s.timemodified, s.timemarked,\n CASE WHEN s.timemarked > 0 AND s.timemarked >= s.timemodified THEN 1\n ELSE 0 END AS status "; $sql = 'FROM {user} u ' . 'LEFT JOIN {assignment_submissions} s ON u.id = s.userid AND s.assignment = ' . $this->assignment->id . ' ' . 'WHERE ' . $where . 'u.id IN (' . implode(',', $users) . ') '; if ($sort = flexible_table::get_sort_for_table('mod-assignment-submissions')) { $sort = 'ORDER BY ' . $sort . ' '; } $auser = $DB->get_records_sql($select . $sql . $sort, null, $offset, 2); if (is_array($auser) && count($auser) > 1) { $nextuser = next($auser); $nextid = $nextuser->id; } } if ($submission->teacher) { $teacher = $DB->get_record('user', array('id' => $submission->teacher)); } else { global $USER; $teacher = $USER; } $this->preprocess_submission($submission); $mformdata = new stdClass(); $mformdata->context = $this->context; $mformdata->maxbytes = $this->course->maxbytes; $mformdata->courseid = $this->course->id; $mformdata->teacher = $teacher; $mformdata->assignment = $assignment; $mformdata->submission = $submission; $mformdata->lateness = $this->display_lateness($submission->timemodified); $mformdata->auser = $auser; $mformdata->user = $user; $mformdata->offset = $offset; $mformdata->userid = $userid; $mformdata->cm = $this->cm; $mformdata->grading_info = $grading_info; $mformdata->enableoutcomes = $CFG->enableoutcomes; $mformdata->grade = $this->assignment->grade; $mformdata->gradingdisabled = $gradingdisabled; $mformdata->nextid = $nextid; $mformdata->submissioncomment = $submission->submissioncomment; $mformdata->submissioncommentformat = FORMAT_HTML; $mformdata->submission_content = $this->print_user_files($user->id, true); $mformdata->filter = $filter; $mformdata->mailinfo = get_user_preferences('assignment_mailinfo', 0); if ($assignment->assignmenttype == 'upload') { $mformdata->fileui_options = array('subdirs' => 1, 'maxbytes' => $assignment->maxbytes, 'maxfiles' => $assignment->var1, 'accepted_types' => '*', 'return_types' => FILE_INTERNAL); } elseif ($assignment->assignmenttype == 'uploadsingle') { $mformdata->fileui_options = array('subdirs' => 0, 'maxbytes' => $CFG->userquota, 'maxfiles' => 1, 'accepted_types' => '*', 'return_types' => FILE_INTERNAL); } $advancedgradingwarning = false; $gradingmanager = get_grading_manager($this->context, 'mod_assignment', 'submission'); if ($gradingmethod = $gradingmanager->get_active_method()) { $controller = $gradingmanager->get_controller($gradingmethod); if ($controller->is_form_available()) { $itemid = null; if (!empty($submission->id)) { $itemid = $submission->id; } if ($gradingdisabled && $itemid) { $mformdata->advancedgradinginstance = $controller->get_current_instance($USER->id, $itemid); } else { if (!$gradingdisabled) { $instanceid = optional_param('advancedgradinginstanceid', 0, PARAM_INT); $mformdata->advancedgradinginstance = $controller->get_or_create_instance($instanceid, $USER->id, $itemid); } } } else { $advancedgradingwarning = $controller->form_unavailable_notification(); } } $submitform = new assignment_grading_form(null, $mformdata); if (!$display) { $ret_data = new stdClass(); $ret_data->mform = $submitform; if (isset($mformdata->fileui_options)) { $ret_data->fileui_options = $mformdata->fileui_options; } return $ret_data; } if ($submitform->is_cancelled()) { redirect('submissions.php?id=' . $this->cm->id); } $submitform->set_data($mformdata); $PAGE->set_title($this->course->fullname . ': ' . get_string('feedback', 'assignment') . ' - ' . fullname($user, true)); $PAGE->set_heading($this->course->fullname); $PAGE->navbar->add(get_string('submissions', 'assignment'), new moodle_url('/mod/assignment/submissions.php', array('id' => $cm->id))); $PAGE->navbar->add(fullname($user, true)); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('feedback', 'assignment') . ': ' . fullname($user, true)); // display mform here... if ($advancedgradingwarning) { echo $OUTPUT->notification($advancedgradingwarning, 'error'); } $submitform->display(); $customfeedback = $this->custom_feedbackform($submission, true); if (!empty($customfeedback)) { echo $customfeedback; } echo $OUTPUT->footer(); }
/** * Print course participants. Called by message_print_contact_selector() * @param object $context the course context * @param int $courseid the course ID * @param string $contactselecturl the url to send the user to when a contact's name is clicked * @param bool $showactionlinks show action links (add/remove contact etc) next to the users * @param string $titletodisplay Optionally specify a title to display above the participants * @param int $page if there are so many users listed that they have to be split into pages what page are we viewing * @param object $user2 the user $user1 is talking to. They will be highlighted if they appear in the list of participants * @return void */ function message_print_participants($context, $courseid, $contactselecturl=null, $showactionlinks=true, $titletodisplay=null, $page=0, $user2=null) { global $DB, $USER, $PAGE, $OUTPUT; if (empty($titletodisplay)) { $titletodisplay = get_string('participants'); } $countparticipants = count_enrolled_users($context); $participants = get_enrolled_users($context, '', 0, 'u.*', '', $page*MESSAGE_CONTACTS_PER_PAGE, MESSAGE_CONTACTS_PER_PAGE); $pagingbar = new paging_bar($countparticipants, $page, MESSAGE_CONTACTS_PER_PAGE, $PAGE->url, 'page'); echo $OUTPUT->render($pagingbar); echo html_writer::start_tag('table', array('id' => 'message_participants', 'class' => 'boxaligncenter', 'cellspacing' => '2', 'cellpadding' => '0', 'border' => '0')); echo html_writer::start_tag('tr'); echo html_writer::tag('td', $titletodisplay, array('colspan' => 3, 'class' => 'heading')); echo html_writer::end_tag('tr'); //todo these need to come from somewhere if the course participants list is to show users with unread messages $iscontact = true; $isblocked = false; foreach ($participants as $participant) { if ($participant->id != $USER->id) { $participant->messagecount = 0;//todo it would be nice if the course participant could report new messages message_print_contactlist_user($participant, $iscontact, $isblocked, $contactselecturl, $showactionlinks, $user2); } } echo html_writer::end_tag('table'); }
/** * @global object * @global object * @global object * @uses CONTEXT_MODULE * @param object $choice * @param object $cm * @param int $groupmode * @param bool $onlyactive Whether to get response data for active users only. * @return array */ function choice_get_response_data($choice, $cm, $groupmode, $onlyactive) { global $CFG, $USER, $DB; $context = context_module::instance($cm->id); /// Get the current group if ($groupmode > 0) { $currentgroup = groups_get_activity_group($cm); } else { $currentgroup = 0; } /// Initialise the returned array, which is a matrix: $allresponses[responseid][userid] = responseobject $allresponses = array(); /// First get all the users who have access here /// To start with we assume they are all "unanswered" then move them later $allresponses[0] = get_enrolled_users($context, 'mod/choice:choose', $currentgroup, user_picture::fields('u', array('idnumber')), null, 0, 0, $onlyactive); /// Get all the recorded responses for this choice $rawresponses = $DB->get_records('choice_answers', array('choiceid' => $choice->id)); /// Use the responses to move users into the correct column if ($rawresponses) { $answeredusers = array(); foreach ($rawresponses as $response) { if (isset($allresponses[0][$response->userid])) { // This person is enrolled and in correct group $allresponses[0][$response->userid]->timemodified = $response->timemodified; $allresponses[$response->optionid][$response->userid] = clone $allresponses[0][$response->userid]; $allresponses[$response->optionid][$response->userid]->answerid = $response->id; $answeredusers[] = $response->userid; } } foreach ($answeredusers as $answereduser) { unset($allresponses[0][$answereduser]); } } return $allresponses; }
/** * Return all course participant for a given course * * @deprecated * @param integer $courseid * @return array of user */ function get_course_participants($courseid) { return get_enrolled_users(get_context_instance(CONTEXT_COURSE, $courseid)); }
/** * Fetches and returns a count of all the users that will be shown on this page. * @param boolean $groups include groups limit * @param boolean $users include users limit - default false, used for searching purposes * @return int Count of users */ public function get_numusers($groups = true, $users = false) { global $CFG, $DB; $userwheresql = ""; $groupsql = ""; $groupwheresql = ""; // Limit to users with a gradeable role. list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0'); // Limit to users with an active enrollment. list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context); // We want to query both the current context and parent contexts. list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($this->context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx'); $params = array_merge($gradebookrolesparams, $enrolledparams, $relatedctxparams); if ($users) { $userwheresql = $this->userwheresql; $params = array_merge($params, $this->userwheresql_params); } if ($groups) { $groupsql = $this->groupsql; $groupwheresql = $this->groupwheresql; $params = array_merge($params, $this->groupwheresql_params); } $sql = "SELECT DISTINCT u.id\n FROM {user} u\n JOIN ({$enrolledsql}) je\n ON je.id = u.id\n JOIN {role_assignments} ra\n ON u.id = ra.userid\n {$groupsql}\n WHERE ra.roleid {$gradebookrolessql}\n AND u.deleted = 0\n {$userwheresql}\n {$groupwheresql}\n AND ra.contextid {$relatedctxsql}"; $selectedusers = $DB->get_records_sql($sql, $params); $count = 0; // Check if user's enrolment is active and should be displayed. if (!empty($selectedusers)) { $coursecontext = $this->context->get_course_context(true); $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $coursecontext); if ($showonlyactiveenrol) { $useractiveenrolments = get_enrolled_users($coursecontext, '', 0, 'u.id', null, 0, 0, true); } foreach ($selectedusers as $id => $value) { if (!$showonlyactiveenrol || $showonlyactiveenrol && array_key_exists($id, $useractiveenrolments)) { $count++; } } } return $count; }
/** * @global object * @global object * @global object * @uses CONTEXT_MODULE * @param object $choicegroup * @param object $cm * @return array */ function choicegroup_get_response_data($choicegroup, $cm) { // Initialise the returned array, which is a matrix: $allresponses[responseid][userid] = responseobject. static $allresponses = array(); if (count($allresponses)) { return $allresponses; } // First get all the users who have access here. // To start with we assume they are all "unanswered" then move them later. $ctx = \context_module::instance($cm->id); $users = get_enrolled_users($ctx, 'mod/choicegroup:choose', 0, user_picture::fields('u', array('idnumber')), 'u.lastname ASC,u.firstname ASC'); if ($users) { $modinfo = get_fast_modinfo($cm->course); $cminfo = $modinfo->get_cm($cm->id); $availability = new \core_availability\info_module($cminfo); $users = $availability->filter_user_list($users); } $allresponses[0] = $users; foreach ($allresponses[0] as $user) { $currentanswers = choicegroup_get_user_answer($choicegroup, $user, true); if ($currentanswers != false) { foreach ($currentanswers as $current) { $allresponses[$current->id][$user->id] = clone $allresponses[0][$user->id]; $allresponses[$current->id][$user->id]->timemodified = $current->timeuseradded; } // Remove from unanswered column. unset($allresponses[0][$user->id]); } } return $allresponses; }
public function wiki_print_subwiki_selector($wiki, $subwiki, $page, $pagetype = 'view') { global $CFG, $USER; require_once($CFG->dirroot . '/user/lib.php'); switch ($pagetype) { case 'files': $baseurl = new moodle_url('/mod/wiki/files.php'); break; case 'view': default: $baseurl = new moodle_url('/mod/wiki/view.php'); break; } $cm = get_coursemodule_from_instance('wiki', $wiki->id); $context = get_context_instance(CONTEXT_MODULE, $cm->id); // @TODO: A plenty of duplicated code below this lines. // Create private functions. switch (groups_get_activity_groupmode($cm)) { case NOGROUPS: if ($wiki->wikimode == 'collaborative') { // No need to print anything return; } else if ($wiki->wikimode == 'individual') { // We have private wikis here $view = has_capability('mod/wiki:viewpage', $context); $manage = has_capability('mod/wiki:managewiki', $context); // Only people with these capabilities can view all wikis if ($view && $manage) { // @TODO: Print here a combo that contains all users. $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $options[$user->id] = fullname($user); } echo $this->output->container_start('wiki_right'); $params = array('wid' => $wiki->id, 'title' => $page->title); if ($pagetype == 'files') { $params['pageid'] = $page->id; } $baseurl->params($params); $name = 'uid'; $selected = $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected); echo $this->output->container_end(); } return; } else { // error return; } case SEPARATEGROUPS: if ($wiki->wikimode == 'collaborative') { // We need to print a select to choose a course group $params = array('wid'=>$wiki->id, 'title'=>$page->title); if ($pagetype == 'files') { $params['pageid'] = $page->id; } $baseurl->params($params); echo $this->output->container_start('wiki_right'); groups_print_activity_menu($cm, $baseurl->out()); echo $this->output->container_end(); return; } else if ($wiki->wikimode == 'individual') { // @TODO: Print here a combo that contains all users of that subwiki. $view = has_capability('mod/wiki:viewpage', $context); $manage = has_capability('mod/wiki:managewiki', $context); // Only people with these capabilities can view all wikis if ($view && $manage) { $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $groups = groups_get_all_groups($cm->course, $user->id); if (!empty($groups)) { foreach ($groups as $group) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } else { $name = get_string('notingroup', 'wiki'); $options[0][$name]['0' . '-' . $user->id] = fullname($user); } } } else { $group = groups_get_group($subwiki->groupid); $users = groups_get_members($subwiki->groupid); foreach ($users as $user) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } echo $this->output->container_start('wiki_right'); $params = array('wid' => $wiki->id, 'title' => $page->title); if ($pagetype == 'files') { $params['pageid'] = $page->id; } $baseurl->params($params); $name = 'groupanduser'; $selected = $subwiki->groupid . '-' . $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected); echo $this->output->container_end(); return; } else { // error return; } CASE VISIBLEGROUPS: if ($wiki->wikimode == 'collaborative') { // We need to print a select to choose a course group $params = array('wid'=>$wiki->id, 'title'=>urlencode($page->title)); if ($pagetype == 'files') { $params['pageid'] = $page->id; } $baseurl->params($params); echo $this->output->container_start('wiki_right'); groups_print_activity_menu($cm, $baseurl->out()); echo $this->output->container_end(); return; } else if ($wiki->wikimode == 'individual') { $users = get_enrolled_users($context); $options = array(); foreach ($users as $user) { $groups = groups_get_all_groups($cm->course, $user->id); if (!empty($groups)) { foreach ($groups as $group) { $options[$group->id][$group->name][$group->id . '-' . $user->id] = fullname($user); } } else { $name = get_string('notingroup', 'wiki'); $options[0][$name]['0' . '-' . $user->id] = fullname($user); } } echo $this->output->container_start('wiki_right'); $params = array('wid' => $wiki->id, 'title' => $page->title); if ($pagetype == 'files') { $params['pageid'] = $page->id; } $baseurl->params($params); $name = 'groupanduser'; $selected = $subwiki->groupid . '-' . $subwiki->userid; echo $this->output->single_select($baseurl, $name, $options, $selected); echo $this->output->container_end(); return; } else { // error return; } default: // error return; } }
/** * MDL-27591 made this method obsolete. */ public function get_users($groupid = 0, $page = 1) { global $DB, $CFG; // Fields we need from the user table. $userfields = user_picture::fields('u', array('username', 'idnumber', 'institution', 'department')); if (isset($this->pageparams->sort) and $this->pageparams->sort == ATT_SORT_FIRSTNAME) { $orderby = "u.firstname ASC, u.lastname ASC, u.idnumber ASC, u.institution ASC, u.department ASC"; } else { $orderby = "u.lastname ASC, u.firstname ASC, u.idnumber ASC, u.institution ASC, u.department ASC"; } if ($page) { $usersperpage = $this->pageparams->perpage; if (!empty($CFG->enablegroupmembersonly) and $this->cm->groupmembersonly) { $startusers = ($page - 1) * $usersperpage; if ($groupid == 0) { $groups = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id')); } else { $groups = $groupid; } $users = get_users_by_capability($this->context, 'mod/attendance:canbelisted', $userfields . ',u.id, u.firstname, u.lastname, u.email', $orderby, $startusers, $usersperpage, $groups, '', false, true); } else { $startusers = ($page - 1) * $usersperpage; $users = get_enrolled_users($this->context, 'mod/attendance:canbelisted', $groupid, $userfields, $orderby, $startusers, $usersperpage); } } else { if (!empty($CFG->enablegroupmembersonly) and $this->cm->groupmembersonly) { if ($groupid == 0) { $groups = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id')); } else { $groups = $groupid; } $users = get_users_by_capability($this->context, 'mod/attendance:canbelisted', $userfields . ',u.id, u.firstname, u.lastname, u.email', $orderby, '', '', $groups, '', false, true); } else { $users = get_enrolled_users($this->context, 'mod/attendance:canbelisted', $groupid, $userfields, $orderby); } } // Add a flag to each user indicating whether their enrolment is active. if (!empty($users)) { list($sql, $params) = $DB->get_in_or_equal(array_keys($users), SQL_PARAMS_NAMED, 'usid0'); // See CONTRIB-4868. $mintime = 'MIN(CASE WHEN (ue.timestart > :zerotime) THEN ue.timestart ELSE ue.timecreated END)'; $maxtime = 'CASE WHEN MIN(ue.timeend) = 0 THEN 0 ELSE MAX(ue.timeend) END'; // See CONTRIB-3549. $sql = "SELECT ue.userid, MIN(ue.status) as status,\n {$mintime} AS mintime,\n {$maxtime} AS maxtime\n FROM {user_enrolments} ue\n JOIN {enrol} e ON e.id = ue.enrolid\n WHERE ue.userid {$sql}\n AND e.status = :estatus\n AND e.courseid = :courseid\n GROUP BY ue.userid"; $params += array('zerotime' => 0, 'estatus' => ENROL_INSTANCE_ENABLED, 'courseid' => $this->course->id); $enrolments = $DB->get_records_sql($sql, $params); foreach ($users as $user) { $users[$user->id]->enrolmentstatus = $enrolments[$user->id]->status; $users[$user->id]->enrolmentstart = $enrolments[$user->id]->mintime; $users[$user->id]->enrolmentend = $enrolments[$user->id]->maxtime; $users[$user->id]->type = 'standard'; // Mark as a standard (not a temporary) user. } } // Add the 'temporary' users to this list. $tempusers = $DB->get_records('attendance_tempusers', array('courseid' => $this->course->id)); foreach ($tempusers as $tempuser) { $users[] = self::tempuser_to_user($tempuser); } return $users; }
/** * This api generates html to be displayed to teachers in print overview section, related to the grading status of the given * assignment's submissions. * * @param array $unmarkedsubmissions list of submissions of that are currently unmarked indexed by assignment id. * @param string $sqlassignmentids sql clause used to filter open assignments. * @param array $assignmentidparams sql params used to filter open assignments. * @param stdClass $assignment current assignment * @param context $context context of the assignment. * * @return bool|string html to display , false if nothing needs to be displayed. * @throws coding_exception */ function assign_get_grade_details_for_print_overview(&$unmarkedsubmissions, $sqlassignmentids, $assignmentidparams, $assignment, $context) { global $DB; if (!isset($unmarkedsubmissions)) { // Build up and array of unmarked submissions indexed by assignment id/ userid // for use where the user has grading rights on assignment. $dbparams = array_merge(array(ASSIGN_SUBMISSION_STATUS_SUBMITTED), $assignmentidparams); $rs = $DB->get_recordset_sql('SELECT s.assignment as assignment, s.userid as userid, s.id as id, s.status as status, g.timemodified as timegraded FROM {assign_submission} s LEFT JOIN {assign_grades} g ON s.userid = g.userid AND s.assignment = g.assignment AND g.attemptnumber = s.attemptnumber WHERE ( g.timemodified is NULL OR s.timemodified > g.timemodified OR g.grade IS NULL ) AND s.timemodified IS NOT NULL AND s.status = ? AND s.latest = 1 AND s.assignment ' . $sqlassignmentids, $dbparams); $unmarkedsubmissions = array(); foreach ($rs as $rd) { $unmarkedsubmissions[$rd->assignment][$rd->userid] = $rd->id; } $rs->close(); } // Count how many people can submit. $submissions = 0; if ($students = get_enrolled_users($context, 'mod/assign:view', 0, 'u.id')) { foreach ($students as $student) { if (isset($unmarkedsubmissions[$assignment->id][$student->id])) { $submissions++; } } } if ($submissions) { $urlparams = array('id' => $assignment->coursemodule, 'action' => 'grading'); $url = new moodle_url('/mod/assign/view.php', $urlparams); $gradedetails = '<div class="details">' . '<a href="' . $url . '">' . get_string('submissionsnotgraded', 'assign', $submissions) . '</a></div>'; return $gradedetails; } else { return false; } }
/** * Foreach participant in the course - assign them a random id. * * @param int $assignid The assignid to lookup */ public static function allocate_unique_ids($assignid) { global $DB; $cm = get_coursemodule_from_instance('assign', $assignid, 0, false, MUST_EXIST); $context = context_module::instance($cm->id); $currentgroup = groups_get_activity_group($cm, true); $users = get_enrolled_users($context, "mod/assign:submit", $currentgroup, 'u.id'); // Shuffle the users. shuffle($users); $record = new stdClass(); $record->assignment = $assignid; foreach ($users as $user) { $record = $DB->get_record('assign_user_mapping', array('assignment' => $assignid, 'userid' => $user->id), 'id'); if (!$record) { $record = new stdClass(); $record->userid = $user->id; $DB->insert_record('assign_user_mapping', $record); } } }
/** * This function is used to generate and display selector form * * @global stdClass $USER * @global stdClass $CFG * @global moodle_database $DB * @global core_renderer $OUTPUT * @global stdClass $SESSION * @uses CONTEXT_SYSTEM * @uses COURSE_MAX_COURSES_PER_DROPDOWN * @uses CONTEXT_COURSE * @uses SEPARATEGROUPS * @param stdClass $course course instance * @param int $selecteduser id of the selected user * @param string $selecteddate Date selected * @param string $modname course_module->id * @param string $modid number or 'site_errors' * @param string $modaction an action as recorded in the logs * @param int $selectedgroup Group to display * @param int $showcourses whether to show courses if we're over our limit. * @param int $showusers whether to show users if we're over our limit. * @param string $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel) * @return void */ function report_plog_print_selector_form($student, $startdate = 0, $course, $metric, $test) { global $USER, $CFG, $DB, $OUTPUT, $SESSION; $sitecontext = context_system::instance(); $context = context_course::instance($course->id); if (has_capability('report/plog:viewcourse', $context)) { $showusers = 1; } else { $showusers = 0; } //probably remove this - not currently worried about groups (should we be though?) /// Setup for group handling. if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { $selectedgroup = -1; $showgroups = false; } else { if ($course->groupmode) { $showgroups = true; } else { $selectedgroup = 0; $showgroups = false; } } if ($selectedgroup === -1) { if (isset($SESSION->currentgroup[$course->id])) { $selectedgroup = $SESSION->currentgroup[$course->id]; } else { $selectedgroup = groups_get_all_groups($course->id, $USER->id); if (is_array($selectedgroup)) { $selectedgroup = array_shift(array_keys($selectedgroup)); $SESSION->currentgroup[$course->id] = $selectedgroup; } else { $selectedgroup = 0; } } } // Get all the possible users $users = array(); // Define limitfrom and limitnum for queries below // If $showusers is enabled... don't apply limitfrom and limitnum $limitfrom = empty($showusers) ? 0 : ''; $limitnum = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : ''; //this needs to be modified so we don't include admin and tutors for this course in the list? $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname', null, $limitfrom, $limitnum); if ($showusers) { if ($courseusers) { foreach ($courseusers as $courseuser) { $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context)); } } $users[$CFG->siteguest] = get_string('guestuser'); } //echo $course->id; //$n = "select distinct clusteringname from cluster_runs r where r.courseid = $course->id"; $n = "select distinct clusteringname from cluster_runs r where r.courseid = {$course->id}"; $metrica = $DB->get_records_sql($n); //there has to be a better way of doing this... $metrics = array(); foreach ($metrica as $row) { $metrics[] = $row->clusteringname; } $strftimedate = get_string("strftimedate"); $strftimedaydate = get_string("strftimedaydate"); asort($users); $timenow = time(); // GMT // What day is it now for the user, and when is midnight that day (in GMT). $timemidnight = $today = usergetmidnight($timenow); // Put today up the top of the list //$dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) ); $dates = array(); if (!$course->startdate or $course->startdate > $timenow) { $course->startdate = $course->timecreated; } //want to change this so we have a number of intervals //from start of course //last week //last fortnight //last month $numdates = 1; while ($timemidnight > $course->startdate and $numdates < 5) { $timemidnight = $timemidnight - 604800; //number of seconds in a week $timenow = $timenow - 604800; $dates["{$timemidnight}"] = $numdates . " weeks:" . userdate($timenow, $strftimedaydate); $numdates++; } echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/report/plog/index.php\" method=\"get\">\n"; echo "<div>\n"; echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n"; echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n"; echo "<input type=\"hidden\" name=\"test\" value=\"{$test}\" />\n"; if ($showusers) { echo html_writer::label(get_string('selctauser'), 'menuuser', false, array('class' => 'accesshide')); echo html_writer::select($users, "student", $student); } echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide')); echo html_writer::select($dates, "startdate", $startdate, get_string("alldays")); echo '<select id="menumetric" class="select menumetric" name="metric">'; foreach ($metrics as $metric) { echo "<option value='{$metric}'>{$metric}</option>"; } echo '</select>'; //echo html_writer::select($metrics, "metric", $metric, "metric"); echo '<input type="submit" value="' . get_string('gettheselogs') . '" />'; echo '</div>'; echo '</form>'; }
/** * Returns the user who is responsible for self enrolments in given instance. * * Usually it is the first editing teacher - the person with "highest authority" * as defined by sort_by_roleassignment_authority() having 'enrol/self:manage' * capability. * * @param int $instanceid enrolment instance id * @return stdClass user record */ protected function get_enroller($instanceid) { global $DB; if ($this->lasternollerinstanceid == $instanceid and $this->lasternoller) { return $this->lasternoller; } $instance = $DB->get_record('enrol', array('id' => $instanceid, 'enrol' => $this->get_name()), '*', MUST_EXIST); $context = context_course::instance($instance->courseid); if ($users = get_enrolled_users($context, 'enrol/self:manage')) { $users = sort_by_roleassignment_authority($users, $context); $this->lasternoller = reset($users); unset($users); } else { $this->lasternoller = parent::get_enroller($instanceid); } $this->lasternollerinstanceid = $instanceid; return $this->lasternoller; }
/** * 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); }