/** * Finds all subscribed users * * @param string $search * @return array */ public function find_users($search) { global $DB; list($wherecondition, $params) = $this->search_sql($search, 'u'); $params['twfid'] = $this->twfid; // only active enrolled or everybody on the frontpage list($esql, $eparams) = get_enrolled_sql($this->context, '', $this->currentgroup, true); $fields = $this->required_fields_sql('u'); list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); $params = array_merge($params, $eparams, $sortparams); $subscribers = $DB->get_records_sql("SELECT {$fields}\n FROM {user} u\n JOIN ({$esql}) je ON je.id = u.id\n JOIN {twf_subscriptions} s ON s.userid = u.id\n WHERE {$wherecondition} AND s.twf = :twfid\n ORDER BY {$sort}", $params); $cm = get_coursemodule_from_instance('twf', $this->twfid); $modinfo = get_fast_modinfo($cm->course); $info = new \core_availability\info_module($modinfo->get_cm($cm->id)); $subscribers = $info->filter_user_list($subscribers); return array(get_string("existingsubscribers", 'twf') => $subscribers); }
/** * If dynamic data for this course-module is not yet available, gets it. * * This function is automatically called when requesting any course_modinfo property * that can be modified by modules (have a set_xxx method). * * Dynamic data is data which does not come directly from the cache but is calculated at * runtime based on the current user. Primarily this concerns whether the user can access * the module or not. * * As part of this function, the module's _cm_info_dynamic function from its lib.php will * be called (if it exists). * @return void */ private function obtain_dynamic_data() { global $CFG; $userid = $this->modinfo->get_user_id(); if ($this->state >= self::STATE_BUILDING_DYNAMIC || $userid == -1) { return; } $this->state = self::STATE_BUILDING_DYNAMIC; if (!empty($CFG->enableavailability)) { require_once $CFG->libdir . '/conditionlib.php'; // Get availability information. $ci = new \core_availability\info_module($this); // Note that the modinfo currently available only includes minimal details (basic data) // but we know that this function does not need anything more than basic data. $this->available = $ci->is_available($this->availableinfo, true, $userid, $this->modinfo); // Check parent section $parentsection = $this->modinfo->get_section_info($this->sectionnum); if (!$parentsection->available) { // Do not store info from section here, as that is already // presented from the section (if appropriate) - just change // the flag $this->available = false; } } else { $this->available = true; } // Update visible state for current user $this->update_user_visible(); // Let module make dynamic changes at this point $this->call_mod_function('cm_info_dynamic'); $this->state = self::STATE_DYNAMIC; }
/** * count users which have not completed the feedback * * @global object * @uses CONTEXT_MODULE * @param cm_info $cm Course-module object * @param int $group single groupid * @param string $sort * @param int $startpage * @param int $pagecount * @return object the userrecords */ function feedback_get_incomplete_users(cm_info $cm, $group = false, $sort = '', $startpage = false, $pagecount = false) { global $DB; $context = context_module::instance($cm->id); //first get all user who can complete this feedback $cap = 'mod/feedback:complete'; $fields = 'u.id, u.username'; if (!($allusers = get_users_by_capability($context, $cap, $fields, $sort, '', '', $group, '', true))) { return false; } // Filter users that are not in the correct group/grouping. $info = new \core_availability\info_module($cm); $allusers = $info->filter_user_list($allusers); $allusers = array_keys($allusers); //now get all completeds $params = array('feedback' => $cm->instance); if (!($completedusers = $DB->get_records_menu('feedback_completed', $params, '', 'userid,id'))) { return $allusers; } $completedusers = array_keys($completedusers); //now strike all completedusers from allusers $allusers = array_diff($allusers, $completedusers); //for paging I use array_slice() if ($startpage !== false and $pagecount !== false) { $allusers = array_slice($allusers, $startpage, $pagecount); } return $allusers; }
/** * get list of possible attendees (i.e., users that can make an appointment) * @param $groups - single group or array of groups - only return * users who are in one of these group(s). * @return array of moodle user records */ public function get_possible_attendees($groups = '') { // TODO does this need to go to the controller? // If full group objects are given, reduce the array to only group ids. if (is_array($groups) && is_object(array_values($groups)[0])) { $groups = array_keys($groups); } $attendees = get_users_by_capability($this->get_context(), 'mod/scheduler:appoint', '', 'lastname, firstname', '', '', $groups, '', false, false, false); $modinfo = get_fast_modinfo($this->courseid); $info = new \core_availability\info_module($modinfo->get_cm($this->cmid)); $attendees = $info->filter_user_list($attendees); return $attendees; }
/** * @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; }
/** * Used in course/lib.php because we need to disable the completion JS if * a completion value affects a conditional activity. * * @param \stdClass $course Moodle course object * @param int $cmid Course-module id * @return bool True if this is used in a condition, false otherwise */ public static function completion_value_used($course, $cmid) { // Have we already worked out a list of required completion values // for this course? If so just use that. if (!array_key_exists($course->id, self::$modsusedincondition)) { // We don't have data for this course, build it. $modinfo = get_fast_modinfo($course); self::$modsusedincondition[$course->id] = array(); // Activities. foreach ($modinfo->cms as $othercm) { if (is_null($othercm->availability)) { continue; } $ci = new \core_availability\info_module($othercm); $tree = $ci->get_availability_tree(); foreach ($tree->get_all_children('availability_completion\\condition') as $cond) { self::$modsusedincondition[$course->id][$cond->cmid] = true; } } // Sections. foreach ($modinfo->get_section_info_all() as $section) { if (is_null($section->availability)) { continue; } $ci = new \core_availability\info_section($section); $tree = $ci->get_availability_tree(); foreach ($tree->get_all_children('availability_completion\\condition') as $cond) { self::$modsusedincondition[$course->id][$cond->cmid] = true; } } } return array_key_exists($cmid, self::$modsusedincondition[$course->id]); }
/** * Filter a user list and return only the users that can see the course module based on * groups/permissions etc. It is assumed that the users are pre-filtered to those who are enrolled in the course. * * @category group * @param stdClass|cm_info $cm The course module * @param array $users An array of users, indexed by userid * @return array A filtered list of users that can see the module, indexed by userid. * @deprecated Since Moodle 2.8 */ function groups_filter_users_by_course_module_visible($cm, $users) { debugging('groups_filter_users_by_course_module_visible() is deprecated. ' . 'Replace with a call to \\core_availability\\info_module::filter_user_list(), ' . 'which does basically the same thing but includes other restrictions such ' . 'as profile restrictions.', DEBUG_DEVELOPER); if (empty($users)) { return $users; } // Since this function allows stdclass, let's play it safe and ensure we // do have a cm_info. if (!$cm instanceof cm_info) { $modinfo = get_fast_modinfo($cm->course); $cm = $modinfo->get_cm($cm->id); } $info = new \core_availability\info_module($cm); return $info->filter_user_list($users); }
/** * Returns a list of user objects who are subscribed to this forum. * * @param stdClass $forum The forum record. * @param int $groupid The group id if restricting subscriptions to a group of users, or 0 for all. * @param context_module $context the forum context, to save re-fetching it where possible. * @param string $fields requested user fields (with "u." table prefix). * @param boolean $includediscussionsubscriptions Whether to take discussion subscriptions and unsubscriptions into consideration. * @return array list of users. */ public static function fetch_subscribed_users($forum, $groupid = 0, $context = null, $fields = null, $includediscussionsubscriptions = false) { global $CFG, $DB; if (empty($fields)) { $allnames = get_all_user_name_fields(true, 'u'); $fields = "u.id,\n u.username,\n {$allnames},\n u.maildisplay,\n u.mailformat,\n u.maildigest,\n u.imagealt,\n u.email,\n u.emailstop,\n u.city,\n u.country,\n u.lastaccess,\n u.lastlogin,\n u.picture,\n u.timezone,\n u.theme,\n u.lang,\n u.trackforums,\n u.mnethostid"; } // Retrieve the forum context if it wasn't specified. $context = forum_get_context($forum->id, $context); if (self::is_forcesubscribed($forum)) { $results = \mod_forum\subscriptions::get_potential_subscribers($context, $groupid, $fields, "u.email ASC"); } else { // Only active enrolled users or everybody on the frontpage. list($esql, $params) = get_enrolled_sql($context, '', $groupid, true); $params['forumid'] = $forum->id; if ($includediscussionsubscriptions) { $params['sforumid'] = $forum->id; $params['dsforumid'] = $forum->id; $params['unsubscribed'] = self::FORUM_DISCUSSION_UNSUBSCRIBED; $sql = "SELECT {$fields}\n FROM (\n SELECT userid FROM {forum_subscriptions} s\n WHERE\n s.forum = :sforumid\n UNION\n SELECT userid FROM {forum_discussion_subs} ds\n WHERE\n ds.forum = :dsforumid AND ds.preference <> :unsubscribed\n ) subscriptions\n JOIN {user} u ON u.id = subscriptions.userid\n JOIN ({$esql}) je ON je.id = u.id\n ORDER BY u.email ASC"; } else { $sql = "SELECT {$fields}\n FROM {user} u\n JOIN ({$esql}) je ON je.id = u.id\n JOIN {forum_subscriptions} s ON s.userid = u.id\n WHERE\n s.forum = :forumid\n ORDER BY u.email ASC"; } $results = $DB->get_records_sql($sql, $params); } // Guest user should never be subscribed to a forum. unset($results[$CFG->siteguest]); // Apply the activity module availability resetrictions. $cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course); $modinfo = get_fast_modinfo($forum->course); $info = new \core_availability\info_module($modinfo->get_cm($cm->id)); $results = $info->filter_user_list($results); return $results; }
echo html_writer::table($table); } if ($hasinactive) { echo $OUTPUT->notification(get_string('inactiveoverridehelp', 'lesson'), 'dimmed_text'); } echo html_writer::start_tag('div', array('class' => 'buttons')); $options = array(); if ($groupmode) { if (empty($groups)) { // There are no groups. echo $OUTPUT->notification(get_string('groupsnone', 'lesson'), 'error'); $options['disabled'] = true; } echo $OUTPUT->single_button($overrideediturl->out(true, array('action' => 'addgroup', 'cmid' => $cm->id)), get_string('addnewgroupoverride', 'lesson'), 'post', $options); } else { $users = array(); // See if there are any users in the lesson. $users = get_enrolled_users($context); $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); if (empty($users)) { // There are no users. echo $OUTPUT->notification(get_string('usersnone', 'lesson'), 'error'); $options['disabled'] = true; } echo $OUTPUT->single_button($overrideediturl->out(true, array('action' => 'adduser', 'cmid' => $cm->id)), get_string('addnewuseroverride', 'lesson'), 'get', $options); } echo html_writer::end_tag('div'); echo html_writer::end_tag('div'); // Finish the page. echo $OUTPUT->footer();
/** * Renders HTML to show course module availability information * * @param cm_info $mod * @param array $displayoptions * @return string */ public function course_section_cm_availability(cm_info $mod, $displayoptions = array()) { // If we have available info, always spit it out. if (!empty($mod->availableinfo)) { $availinfo = $mod->availableinfo; } else { $ci = new \core_availability\info_module($mod); $availinfo = $ci->get_full_information(); } if ($availinfo) { $formattedinfo = \core_availability\info::format_info($availinfo, $mod->get_course()); return html_writer::div($formattedinfo, 'availabilityinfo'); } return ''; }
/** * Define this form - called by the parent constructor */ protected function definition() { global $CFG, $DB; $cm = $this->cm; $mform = $this->_form; $mform->addElement('header', 'override', get_string('override', 'lesson')); if ($this->groupmode) { // Group override. if ($this->groupid) { // There is already a groupid, so freeze the selector. $groupchoices = array(); $groupchoices[$this->groupid] = groups_get_group_name($this->groupid); $mform->addElement('select', 'groupid', get_string('overridegroup', 'lesson'), $groupchoices); $mform->freeze('groupid'); } else { // Prepare the list of groups. $groups = groups_get_all_groups($cm->course); if (empty($groups)) { // Generate an error. $link = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id)); print_error('groupsnone', 'lesson', $link); } $groupchoices = array(); foreach ($groups as $group) { $groupchoices[$group->id] = $group->name; } unset($groups); if (count($groupchoices) == 0) { $groupchoices[0] = get_string('none'); } $mform->addElement('select', 'groupid', get_string('overridegroup', 'lesson'), $groupchoices); $mform->addRule('groupid', get_string('required'), 'required', null, 'client'); } } else { // User override. if ($this->userid) { // There is already a userid, so freeze the selector. $user = $DB->get_record('user', array('id' => $this->userid)); $userchoices = array(); $userchoices[$this->userid] = fullname($user); $mform->addElement('select', 'userid', get_string('overrideuser', 'lesson'), $userchoices); $mform->freeze('userid'); } else { // Prepare the list of users. $users = get_enrolled_users($this->context, '', 0, 'u.id, u.email, ' . get_all_user_name_fields(true, 'u')); // Filter users based on any fixed restrictions (groups, profile). $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); if (empty($users)) { // Generate an error. $link = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id)); print_error('usersnone', 'lesson', $link); } $userchoices = array(); $canviewemail = in_array('email', get_extra_user_fields($this->context)); foreach ($users as $id => $user) { if (empty($invalidusers[$id]) || !empty($override) && $id == $override->userid) { if ($canviewemail) { $userchoices[$id] = fullname($user) . ', ' . $user->email; } else { $userchoices[$id] = fullname($user); } } } unset($users); if (count($userchoices) == 0) { $userchoices[0] = get_string('none'); } $mform->addElement('searchableselector', 'userid', get_string('overrideuser', 'lesson'), $userchoices); $mform->addRule('userid', get_string('required'), 'required', null, 'client'); } } // Password. // This field has to be above the date and timelimit fields, // otherwise browsers will clear it when those fields are changed. $mform->addElement('passwordunmask', 'password', get_string('usepassword', 'lesson')); $mform->setType('password', PARAM_TEXT); $mform->addHelpButton('password', 'usepassword', 'lesson'); $mform->setDefault('password', $this->lesson->password); // Open and close dates. $mform->addElement('date_time_selector', 'available', get_string('available', 'lesson'), array('optional' => true)); $mform->setDefault('available', $this->lesson->available); $mform->addElement('date_time_selector', 'deadline', get_string('deadline', 'lesson'), array('optional' => true)); $mform->setDefault('deadline', $this->lesson->deadline); // Lesson time limit. $mform->addElement('duration', 'timelimit', get_string('timelimit', 'lesson'), array('optional' => true)); if ($this->lesson->timelimit != 0) { $mform->setDefault('timelimit', 0); } else { $mform->setDefault('timelimit', $this->lesson->timelimit); } // Try a question again. $mform->addElement('selectyesno', 'review', get_string('displayreview', 'lesson')); $mform->addHelpButton('review', 'displayreview', 'lesson'); $mform->setDefault('review', $this->lesson->review); // Number of attempts. $numbers = array(); for ($i = 10; $i > 0; $i--) { $numbers[$i] = $i; } $mform->addElement('select', 'maxattempts', get_string('maximumnumberofattempts', 'lesson'), $numbers); $mform->addHelpButton('maxattempts', 'maximumnumberofattempts', 'lesson'); $mform->setDefault('maxattempts', $this->lesson->maxattempts); // Retake allowed. $mform->addElement('selectyesno', 'retake', get_string('retakesallowed', 'lesson')); $mform->addHelpButton('retake', 'retakesallowed', 'lesson'); $mform->setDefault('retake', $this->lesson->retake); // Submit buttons. $mform->addElement('submit', 'resetbutton', get_string('reverttodefaults', 'lesson')); $buttonarray = array(); $buttonarray[] = $mform->createElement('submit', 'submitbutton', get_string('save', 'lesson')); $buttonarray[] = $mform->createElement('submit', 'againbutton', get_string('saveoverrideandstay', 'lesson')); $buttonarray[] = $mform->createElement('cancel'); $mform->addGroup($buttonarray, 'buttonbar', '', array(' '), false); $mform->closeHeaderBefore('buttonbar'); }
/** * Return conditionally unavailable elements. * @param $course * @return array * @throws \coding_exception */ public static function conditionally_unavailable_elements($course) { $cancomplete = isloggedin() && !isguestuser(); $unavailablesections = []; $unavailablemods = []; $information = ''; if ($cancomplete) { $completioninfo = new \completion_info($course); if ($completioninfo->is_enabled()) { $modinfo = get_fast_modinfo($course); $sections = $modinfo->get_section_info_all(); foreach ($sections as $number => $section) { $ci = new \core_availability\info_section($section); if (!$ci->is_available($information, true)) { $unavailablesections[] = $number; } } foreach ($modinfo->get_cms() as $mod) { $ci = new \core_availability\info_module($mod); if (!$ci->is_available($information, true)) { $unavailablemods[] = $mod->id; } } } } return [$unavailablesections, $unavailablemods]; }
/** * Finds all potential users * * Potential subscribers are all enroled users who are not already subscribed. * * @param string $search * @return array */ public function find_users($search) { global $DB; $whereconditions = array(); list($wherecondition, $params) = $this->search_sql($search, 'u'); if ($wherecondition) { $whereconditions[] = $wherecondition; } if (!$this->forcesubscribed) { $existingids = array(); foreach ($this->existingsubscribers as $group) { foreach ($group as $user) { $existingids[$user->id] = 1; } } if ($existingids) { list($usertest, $userparams) = $DB->get_in_or_equal(array_keys($existingids), SQL_PARAMS_NAMED, 'existing', false); $whereconditions[] = 'u.id ' . $usertest; $params = array_merge($params, $userparams); } } if ($whereconditions) { $wherecondition = 'WHERE ' . implode(' AND ', $whereconditions); } list($esql, $eparams) = get_enrolled_sql($this->context, '', $this->currentgroup, true); $params = array_merge($params, $eparams); $fields = 'SELECT ' . $this->required_fields_sql('u'); $sql = " FROM {user} u\n JOIN ({$esql}) je ON je.id = u.id\n {$wherecondition}"; list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); $order = ' ORDER BY ' . $sort; $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams)); $cm = get_coursemodule_from_instance('forum', $this->forumid); $modinfo = get_fast_modinfo($cm->course); $info = new \core_availability\info_module($modinfo->get_cm($cm->id)); $availableusers = $info->filter_user_list($availableusers); if (empty($availableusers)) { return array(); } // Check to see if there are too many to show sensibly. if (!$this->is_validating()) { $potentialmemberscount = count($availableusers); if ($potentialmemberscount > $this->maxusersperpage) { return $this->too_many_results($search, $potentialmemberscount); } } if ($this->forcesubscribed) { return array(get_string("existingsubscribers", 'forum') => $availableusers); } else { return array(get_string("potentialsubscribers", 'forum') => $availableusers); } }
/** * Define this form - called by the parent constructor */ protected function definition() { global $CFG, $DB; $cm = $this->cm; $mform = $this->_form; $mform->addElement('header', 'override', get_string('override', 'assign')); if ($this->groupmode) { // Group override. if ($this->groupid) { // There is already a groupid, so freeze the selector. $groupchoices = array(); $groupchoices[$this->groupid] = groups_get_group_name($this->groupid); $mform->addElement('select', 'groupid', get_string('overridegroup', 'assign'), $groupchoices); $mform->freeze('groupid'); } else { // Prepare the list of groups. $groups = groups_get_all_groups($cm->course); if (empty($groups)) { // Generate an error. $link = new moodle_url('/mod/assign/overrides.php', array('cmid' => $cm->id)); print_error('groupsnone', 'assign', $link); } $groupchoices = array(); foreach ($groups as $group) { $groupchoices[$group->id] = $group->name; } unset($groups); if (count($groupchoices) == 0) { $groupchoices[0] = get_string('none'); } $mform->addElement('select', 'groupid', get_string('overridegroup', 'assign'), $groupchoices); $mform->addRule('groupid', get_string('required'), 'required', null, 'client'); } } else { // User override. if ($this->userid) { // There is already a userid, so freeze the selector. $user = $DB->get_record('user', array('id' => $this->userid)); $userchoices = array(); $userchoices[$this->userid] = fullname($user); $mform->addElement('select', 'userid', get_string('overrideuser', 'assign'), $userchoices); $mform->freeze('userid'); } else { // Prepare the list of users. $users = get_enrolled_users($this->context, '', 0, 'u.id, u.email, ' . get_all_user_name_fields(true, 'u')); // Filter users based on any fixed restrictions (groups, profile). $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); if (empty($users)) { // Generate an error. $link = new moodle_url('/mod/assign/overrides.php', array('cmid' => $cm->id)); print_error('usersnone', 'assign', $link); } $userchoices = array(); $canviewemail = in_array('email', get_extra_user_fields($this->context)); foreach ($users as $id => $user) { if (empty($invalidusers[$id]) || !empty($override) && $id == $override->userid) { if ($canviewemail) { $userchoices[$id] = fullname($user) . ', ' . $user->email; } else { $userchoices[$id] = fullname($user); } } } unset($users); if (count($userchoices) == 0) { $userchoices[0] = get_string('none'); } $mform->addElement('searchableselector', 'userid', get_string('overrideuser', 'assign'), $userchoices); $mform->addRule('userid', get_string('required'), 'required', null, 'client'); } } $users = $DB->get_fieldset_select('groups_members', 'userid', 'groupid = ?', array($this->groupid)); array_push($users, $this->userid); $extensionmax = 0; foreach ($users as $value) { $extension = $DB->get_record('assign_user_flags', array('assignment' => $this->assign->get_context()->id, 'userid' => $value)); if ($extension) { if ($extensionmax < $extension->extensionduedate) { $extensionmax = $extension->extensionduedate; } } } if ($extensionmax) { $this->assign->get_context()->extensionduedate = $extensionmax; } // Open and close dates. $mform->addElement('date_time_selector', 'allowsubmissionsfromdate', get_string('allowsubmissionsfromdate', 'assign'), array('optional' => true)); $mform->setDefault('allowsubmissionsfromdate', $this->assign->get_context()->allowsubmissionsfromdate); $mform->addElement('date_time_selector', 'duedate', get_string('duedate', 'assign'), array('optional' => true)); $mform->setDefault('duedate', $this->assign->get_context()->duedate); $mform->addElement('date_time_selector', 'cutoffdate', get_string('cutoffdate', 'assign'), array('optional' => true)); $mform->setDefault('cutoffdate', $this->assign->get_context()->cutoffdate); if (isset($this->assign->get_context()->extensionduedate)) { $mform->addElement('static', 'extensionduedate', get_string('extensionduedate', 'assign'), userdate($this->assign->get_context()->extensionduedate)); } // Submit buttons. $mform->addElement('submit', 'resetbutton', get_string('reverttodefaults', 'assign')); $buttonarray = array(); $buttonarray[] = $mform->createElement('submit', 'submitbutton', get_string('save', 'assign')); $buttonarray[] = $mform->createElement('submit', 'againbutton', get_string('saveoverrideandstay', 'assign')); $buttonarray[] = $mform->createElement('cancel'); $mform->addGroup($buttonarray, 'buttonbar', '', array(' '), false); $mform->closeHeaderBefore('buttonbar'); }
/** * Javascript required by both standard header layout and flexpage layout * * @return void */ public static function page_requires_js() { global $CFG, $PAGE, $COURSE, $USER; $PAGE->requires->jquery(); $PAGE->requires->strings_for_js(array('close', 'debugerrors', 'problemsfound', 'error:coverimageexceedsmaxbytes', 'error:coverimageresolutionlow', 'forumtopic', 'forumauthor', 'forumpicturegroup', 'forumreplies', 'forumlastpost', 'hiddencoursestoggle', 'loading', 'more', 'moving', 'movingcount', 'movehere', 'movefailed', 'movingdropsectionhelp', 'movingstartedhelp'), 'theme_snap'); $PAGE->requires->strings_for_js(['ok', 'cancel'], 'moodle'); $PAGE->requires->strings_for_js(['printbook'], 'booktool_print'); // Are we viewing /course/view.php - note, this is different from just checking the page type. // We only ever want to load course.js when on site page or view.php - no point in loading it when on // course settings page, etc. $courseviewpage = local::current_url_path() === '/course/view.php'; $pagehascoursecontent = $PAGE->pagetype === 'site-index' || $courseviewpage; $cancomplete = isloggedin() && !isguestuser(); $unavailablesections = []; $unavailablemods = []; if ($cancomplete) { $completioninfo = new \completion_info($COURSE); if ($completioninfo->is_enabled()) { $modinfo = get_fast_modinfo($COURSE); $sections = $modinfo->get_section_info_all(); foreach ($sections as $number => $section) { $ci = new \core_availability\info_section($section); $information = ''; if (!$ci->is_available($information, true)) { $unavailablesections[] = $number; } } foreach ($modinfo as $mod) { $ci = new \core_availability\info_module($mod); if (!$ci->is_available($information, true)) { $unavailablemods[] = $mod->id; } } } } list($unavailablesections, $unavailablemods) = local::conditionally_unavailable_elements($COURSE); $coursevars = (object) ['id' => $COURSE->id, 'shortname' => $COURSE->shortname, 'contextid' => $PAGE->context->id, 'ajaxurl' => '/course/rest.php', 'unavailablesections' => $unavailablesections, 'unavailablemods' => $unavailablemods, 'enablecompletion' => $COURSE->enablecompletion]; $initvars = [$coursevars, $pagehascoursecontent, get_max_upload_file_size($CFG->maxbytes)]; $PAGE->requires->js_call_amd('theme_snap/snap', 'snapInit', $initvars); // Does the page have editable course content? if ($pagehascoursecontent && $PAGE->user_allowed_editing()) { $canmanageacts = has_capability('moodle/course:manageactivities', context_course::instance($COURSE->id)); if ($canmanageacts && empty($USER->editing)) { $modinfo = get_fast_modinfo($COURSE); $modnamesused = $modinfo->get_used_module_names(); // Temporarily change edit mode to on for course ajax to be included. $USER->editing = true; self::include_course_ajax($COURSE, $modnamesused); $USER->editing = false; } } }
/** * Changes all date restrictions on a course by the specified shift amount. * Used by the course reset feature. * * @param int $courseid Course id * @param int $timeshift Offset in seconds */ public static function update_all_dates($courseid, $timeshift) { global $DB; $modinfo = get_fast_modinfo($courseid); $anychanged = false; // Adjust dates from all course modules. foreach ($modinfo->cms as $cm) { if (!$cm->availability) { continue; } $info = new \core_availability\info_module($cm); $tree = $info->get_availability_tree(); $dates = $tree->get_all_children('availability_date\\condition'); $changed = false; foreach ($dates as $date) { $date->time += $timeshift; $changed = true; } // Save the updated course module. if ($changed) { $DB->set_field('course_modules', 'availability', json_encode($tree->save()), array('id' => $cm->id)); $anychanged = true; } } // Adjust dates from all course sections. foreach ($modinfo->get_section_info_all() as $section) { if (!$section->availability) { continue; } $info = new \core_availability\info_section($section); $tree = $info->get_availability_tree(); $dates = $tree->get_all_children('availability_date\\condition'); $changed = false; foreach ($dates as $date) { $date->time += $timeshift; $changed = true; } // Save the updated course module. if ($changed) { $DB->set_field('course_sections', 'availability', json_encode($tree->save()), array('id' => $section->id)); $anychanged = true; } } // Ensure course cache is cleared if required. if ($anychanged) { rebuild_course_cache($courseid, true); } }
/** * Load a list of users enrolled in the current course with the specified permission and group. * 0 for no group. * * @param int $currentgroup * @param bool $idsonly * @return array List of user records */ public function list_participants($currentgroup, $idsonly) { global $DB; if (empty($currentgroup)) { $currentgroup = 0; } $key = $this->context->id . '-' . $currentgroup . '-' . $this->show_only_active_users(); if (!isset($this->participants[$key])) { list($esql, $params) = get_enrolled_sql($this->context, 'mod/assign:submit', $currentgroup, $this->show_only_active_users()); $fields = 'u.*'; $orderby = 'u.lastname, u.firstname, u.id'; $additionaljoins = ''; $instance = $this->get_instance(); if (!empty($instance->blindmarking)) { $additionaljoins .= " LEFT JOIN {assign_user_mapping} um ON u.id = um.userid AND um.assignment = :assignmentid1 LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid2 AND s.latest = 1 "; $params['assignmentid1'] = (int) $instance->id; $params['assignmentid2'] = (int) $instance->id; $fields .= ', um.id as recordid '; // Sort by submission time first, then by um.id to sort reliably by the blind marking id. // Note, different DBs have different ordering of NULL values. // Therefore we coalesce the current time into the timecreated field, and the max possible integer into // the ID field. $orderby = "COALESCE(s.timecreated, " . time() . ") ASC, COALESCE(s.id, " . PHP_INT_MAX . ") ASC, um.id ASC"; } $sql = "SELECT $fields FROM {user} u JOIN ($esql) je ON je.id = u.id $additionaljoins WHERE u.deleted = 0 ORDER BY $orderby"; $users = $DB->get_records_sql($sql, $params); $cm = $this->get_course_module(); $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); $this->participants[$key] = $users; } if ($idsonly) { $idslist = array(); foreach ($this->participants[$key] as $id => $user) { $idslist[$id] = new stdClass(); $idslist[$id]->id = $id; } return $idslist; } return $this->participants[$key]; }
protected function definition() { global $CFG, $DB; $cm = $this->cm; $mform = $this->_form; $mform->addElement('header', 'override', get_string('override', 'quiz')); if ($this->groupmode) { // Group override. if ($this->groupid) { // There is already a groupid, so freeze the selector. $groupchoices = array(); $groupchoices[$this->groupid] = groups_get_group_name($this->groupid); $mform->addElement('select', 'groupid', get_string('overridegroup', 'quiz'), $groupchoices); $mform->freeze('groupid'); } else { // Prepare the list of groups. $groups = groups_get_all_groups($cm->course); if (empty($groups)) { // Generate an error. $link = new moodle_url('/mod/quiz/overrides.php', array('cmid' => $cm->id)); print_error('groupsnone', 'quiz', $link); } $groupchoices = array(); foreach ($groups as $group) { $groupchoices[$group->id] = $group->name; } unset($groups); if (count($groupchoices) == 0) { $groupchoices[0] = get_string('none'); } $mform->addElement('select', 'groupid', get_string('overridegroup', 'quiz'), $groupchoices); $mform->addRule('groupid', get_string('required'), 'required', null, 'client'); } } else { // User override. if ($this->userid) { // There is already a userid, so freeze the selector. $user = $DB->get_record('user', array('id' => $this->userid)); $userchoices = array(); $userchoices[$this->userid] = fullname($user); $mform->addElement('select', 'userid', get_string('overrideuser', 'quiz'), $userchoices); $mform->freeze('userid'); } else { // Prepare the list of users. $users = array(); list($sort, $sortparams) = users_order_by_sql('u'); if (!empty($sortparams)) { throw new coding_exception('users_order_by_sql returned some query parameters. ' . 'This is unexpected, and a problem because there is no way to pass these ' . 'parameters to get_users_by_capability. See MDL-34657.'); } $users = get_users_by_capability($this->context, 'mod/quiz:attempt', 'u.id, u.email, ' . get_all_user_name_fields(true, 'u'), $sort, '', '', '', '', false, true); // Filter users based on any fixed restrictions (groups, profile). $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); if (empty($users)) { // Generate an error. $link = new moodle_url('/mod/quiz/overrides.php', array('cmid' => $cm->id)); print_error('usersnone', 'quiz', $link); } $userchoices = array(); $canviewemail = in_array('email', get_extra_user_fields($this->context)); foreach ($users as $id => $user) { if (empty($invalidusers[$id]) || !empty($override) && $id == $override->userid) { if ($canviewemail) { $userchoices[$id] = fullname($user) . ', ' . $user->email; } else { $userchoices[$id] = fullname($user); } } } unset($users); if (count($userchoices) == 0) { $userchoices[0] = get_string('none'); } $mform->addElement('searchableselector', 'userid', get_string('overrideuser', 'quiz'), $userchoices); $mform->addRule('userid', get_string('required'), 'required', null, 'client'); } } // Password. // This field has to be above the date and timelimit fields, // otherwise browsers will clear it when those fields are changed. $mform->addElement('passwordunmask', 'password', get_string('requirepassword', 'quiz')); $mform->setType('password', PARAM_TEXT); $mform->addHelpButton('password', 'requirepassword', 'quiz'); $mform->setDefault('password', $this->quiz->password); // Open and close dates. $mform->addElement('date_time_selector', 'timeopen', get_string('quizopen', 'quiz'), mod_quiz_mod_form::$datefieldoptions); $mform->setDefault('timeopen', $this->quiz->timeopen); $mform->addElement('date_time_selector', 'timeclose', get_string('quizclose', 'quiz'), mod_quiz_mod_form::$datefieldoptions); $mform->setDefault('timeclose', $this->quiz->timeclose); // Time limit. $mform->addElement('duration', 'timelimit', get_string('timelimit', 'quiz'), array('optional' => true)); $mform->addHelpButton('timelimit', 'timelimit', 'quiz'); $mform->setDefault('timelimit', $this->quiz->timelimit); // Number of attempts. $attemptoptions = array('0' => get_string('unlimited')); for ($i = 1; $i <= QUIZ_MAX_ATTEMPT_OPTION; $i++) { $attemptoptions[$i] = $i; } $mform->addElement('select', 'attempts', get_string('attemptsallowed', 'quiz'), $attemptoptions); $mform->setDefault('attempts', $this->quiz->attempts); // Submit buttons. $mform->addElement('submit', 'resetbutton', get_string('reverttodefaults', 'quiz')); $buttonarray = array(); $buttonarray[] = $mform->createElement('submit', 'submitbutton', get_string('save', 'quiz')); $buttonarray[] = $mform->createElement('submit', 'againbutton', get_string('saveoverrideandstay', 'quiz')); $buttonarray[] = $mform->createElement('cancel'); $mform->addGroup($buttonarray, 'buttonbar', '', array(' '), false); $mform->closeHeaderBefore('buttonbar'); }
/** * Renders HTML to show course module availability information (for someone who isn't allowed * to see the activity itself, or for staff) * * @param cm_info $mod * @param array $displayoptions * @return string */ public function course_section_cm_availability(cm_info $mod, $displayoptions = array()) { global $CFG; if (!$mod->uservisible) { // this is a student who is not allowed to see the module but might be allowed // to see availability info (i.e. "Available from ...") if (!empty($mod->availableinfo)) { $formattedinfo = \core_availability\info::format_info($mod->availableinfo, $mod->get_course()); $output = html_writer::tag('div', $formattedinfo, array('class' => 'availabilityinfo')); } return $output; } // this is a teacher who is allowed to see module but still should see the // information that module is not available to all/some students $modcontext = context_module::instance($mod->id); $canviewhidden = has_capability('moodle/course:viewhiddenactivities', $modcontext); if ($canviewhidden && !empty($CFG->enableavailability)) { // Don't add availability information if user is not editing and activity is hidden. if ($mod->visible || $this->page->user_is_editing()) { $hidinfoclass = ''; if (!$mod->visible) { $hidinfoclass = 'hide'; } $ci = new \core_availability\info_module($mod); $fullinfo = $ci->get_full_information(); if ($fullinfo) { $formattedinfo = \core_availability\info::format_info($fullinfo, $mod->get_course()); return html_writer::div($formattedinfo, 'availabilityinfo ' . $hidinfoclass); } } } return ''; }
/** * Returns list of user objects that are subscribed to this forum * * @global object * @global object * @param object $course the course * @param forum $forum the forum * @param integer $groupid group id, or 0 for all. * @param object $context the forum context, to save re-fetching it where possible. * @param string $fields requested user fields (with "u." table prefix) * @return array list of users. */ function hsuforum_subscribed_users($course, $forum, $groupid = 0, $context = null, $fields = null) { global $CFG, $DB; $allnames = get_all_user_name_fields(true, 'u'); if (empty($fields)) { $fields = "u.id,\n u.username,\n {$allnames},\n u.maildisplay,\n u.mailformat,\n u.maildigest,\n u.imagealt,\n u.email,\n u.emailstop,\n u.city,\n u.country,\n u.lastaccess,\n u.lastlogin,\n u.picture,\n u.timezone,\n u.theme,\n u.lang,\n u.trackforums,\n u.mnethostid"; } if (empty($context)) { $cm = get_coursemodule_from_instance('hsuforum', $forum->id, $course->id); $context = context_module::instance($cm->id); } if (hsuforum_is_forcesubscribed($forum)) { $results = hsuforum_get_potential_subscribers($context, $groupid, $fields, "u.email ASC"); } else { // only active enrolled users or everybody on the frontpage list($esql, $params) = get_enrolled_sql($context, '', $groupid, true); $params['forumid'] = $forum->id; $results = $DB->get_records_sql("SELECT {$fields}\n FROM {user} u\n JOIN ({$esql}) je ON je.id = u.id\n JOIN {hsuforum_subscriptions} s ON s.userid = u.id\n WHERE s.forum = :forumid\n ORDER BY u.email ASC", $params); } // Guest user should never be subscribed to a forum. unset($results[$CFG->siteguest]); $cm = get_coursemodule_from_instance('hsuforum', $forum->id); $modinfo = get_fast_modinfo($cm->course); $mod = $modinfo->get_cm($cm->id); $info = new \core_availability\info_module($mod); return $info->filter_user_list($results); }
/** * Returns SQL to fetch all enrolled users with the given capability in the current workshop * * The returned array consists of string $sql and the $params array. Note that the $sql can be * empty if a grouping is selected and it has no groups. * * The list is automatically restricted according to any availability restrictions * that apply to user lists (e.g. group, grouping restrictions). * * @param string $capability the name of the capability * @param bool $musthavesubmission ff true, return only users who have already submitted * @param int $groupid 0 means ignore groups, any other value limits the result by group id * @return array of (string)sql, (array)params */ protected function get_users_with_capability_sql($capability, $musthavesubmission, $groupid) { global $CFG; /** @var int static counter used to generate unique parameter holders */ static $inc = 0; $inc++; // If the caller requests all groups and we are using a selected grouping, // recursively call this function for each group in the grouping (this is // needed because get_enrolled_sql only supports a single group). if (empty($groupid) and $this->cm->groupingid) { $groupingid = $this->cm->groupingid; $groupinggroupids = array_keys(groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid, 'g.id')); $sql = array(); $params = array(); foreach ($groupinggroupids as $groupinggroupid) { if ($groupinggroupid > 0) { // just in case in order not to fall into the endless loop list($gsql, $gparams) = $this->get_users_with_capability_sql($capability, $musthavesubmission, $groupinggroupid); $sql[] = $gsql; $params = array_merge($params, $gparams); } } $sql = implode(PHP_EOL . " UNION " . PHP_EOL, $sql); return array($sql, $params); } list($esql, $params) = get_enrolled_sql($this->context, $capability, $groupid, true); $userfields = user_picture::fields('u'); $sql = "SELECT {$userfields}\n FROM {user} u\n JOIN ({$esql}) je ON (je.id = u.id AND u.deleted = 0) "; if ($musthavesubmission) { $sql .= " JOIN {workshop_submissions} ws ON (ws.authorid = u.id AND ws.example = 0 AND ws.workshopid = :workshopid{$inc}) "; $params['workshopid' . $inc] = $this->id; } // If the activity is restricted so that only certain users should appear // in user lists, integrate this into the same SQL. $info = new \core_availability\info_module($this->cm); list($listsql, $listparams) = $info->get_user_list_sql(false); if ($listsql) { $sql .= " JOIN ({$listsql}) restricted ON restricted.id = u.id "; $params = array_merge($params, $listparams); } return array($sql, $params); }
/** * Obtains list of forum subscribers. * @param int $groupid If specified, restricts list to this group id * @return array Array of partial user objects (with enough info to send * email and display them); additionally, if the forum is in group mode, * this includes an ->accessallgroups boolean */ public function get_subscribers($groupid = self::ALL_GROUPS) { global $DB; // Array that will contain result $users = array(); // Get permitted groups $groups = $this->get_permitted_groups(); $subscriptionoption = $this->get_effective_subscription_option(); switch ($subscriptionoption) { case self::SUBSCRIPTION_NOT_PERMITTED: return array(); case self::SUBSCRIPTION_FORCED: case self::SUBSCRIPTION_INITIALLY_SUBSCRIBED: $users = $this->get_auto_subscribers($groupid); // Add $wholeforum = 1 and an empty array() for discussionid // for people who initially subscribed. foreach ($users as $user) { $user->wholeforum = true; $user->discussionids = array(); $user->groupids = array(); } break; default: // The other two cases (initial subscribe, and manual subscribe) // fall through to the standard code below. } $context = $this->get_context(); // For shared forums, we only return the subscribers for the current // clone $clonecheck = ""; if ($this->is_shared()) { $clonecheck = 'AND s.clonecmid = ' . $this->get_course_module_id(); } // Obtain the list of users who have access all groups on the forum, // unless it's in no-groups mode $groupmode = $this->get_group_mode(); if ($groupmode) { // Get a list of user who can access all groups. $aagusers = get_users_by_capability($context, 'moodle/site:accessallgroups', 'u.id'); mod_forumng_utils::add_admin_users($aagusers); } // Get the list of subscribed users. if ($groupid == self::ALL_GROUPS || $groupid == self::NO_GROUPS) { $groupcheck = ''; $groupparams = array(); } else { $groupcheck = "INNER JOIN {groups_members} gm ON gm.userid = u.id AND gm.groupid = ?"; $groupparams = array($groupid); } $rs = $DB->get_recordset_sql($sql = "\nSELECT\n " . mod_forumng_utils::select_username_fields('u', true) . ",\n s.subscribed, s.discussionid, s.groupid, fd.groupid AS discussiongroupid,\n discussiongm.id AS discussiongroupmember, subscriptiongm.id AS subscriptiongroupmember\nFROM\n {forumng_subscriptions} s\n INNER JOIN {user} u ON u.id = s.userid\n {$groupcheck}\n LEFT JOIN {forumng_discussions} fd ON fd.id = s.discussionid\n LEFT JOIN {groups_members} discussiongm ON fd.groupid = discussiongm.groupid\n AND s.userid = discussiongm.userid\n LEFT JOIN {groups_members} subscriptiongm ON s.groupid = subscriptiongm.groupid\n AND s.userid = subscriptiongm.userid\nWHERE\n s.forumngid = ?\n AND (fd.forumngid = ? OR s.discussionid IS NULL)\n {$clonecheck}", array_merge($groupparams, array($this->forumfields->id, $this->forumfields->id))); // Filter the result against the list of allowed users $allowedusers = null; foreach ($rs as $rec) { // Subscribed to the whole forum when subscribed == 1 and disucssionid ==''; // *** Put the allowedusers checks in same part of code so not duplicated if ($rec->subscribed) { // This is a 'subscribe' request if (!$allowedusers) { // Obtain the list of users who are allowed to see the forum. // As get_users_by_capability can be expensive, we only do this // once we know there actually are subscribers (and force rasing memory). raise_memory_limit(MEMORY_EXTRA); $allowedusers = get_users_by_capability($context, 'mod/forumng:viewdiscussion', 'u.id', '', '', '', $groups, '', 0, 0, true); // Filter possible users by activity availability. $avail = new \core_availability\info_module($this->get_course_module()); $allowedusers = $avail->filter_user_list($allowedusers); mod_forumng_utils::add_admin_users($allowedusers); } // Get reference to current user, or make new object if required if (!array_key_exists($rec->u_id, $users)) { $user = mod_forumng_utils::extract_subobject($rec, 'u_'); $user->wholeforum = false; $user->discussionids = array(); $user->groupids = array(); $newuser = true; } else { $user = $users[$rec->u_id]; $newuser = false; } $ok = false; // Subscribed to a discussion. if ($rec->discussionid) { $groupok = !$rec->discussiongroupid || $rec->discussiongroupmember || $groupmode == VISIBLEGROUPS || array_key_exists($user->id, $aagusers); if (array_key_exists($user->id, $allowedusers) && $groupok) { $ok = true; $user->discussionids[$rec->discussionid] = $rec->discussiongroupid; } // Subscribed to a group. } else { if ($rec->groupid) { $groupok = $groupmode == VISIBLEGROUPS || $groupmode == SEPARATEGROUPS && ($rec->subscriptiongroupmember || array_key_exists($user->id, $aagusers)); if (array_key_exists($user->id, $allowedusers) && $groupok) { $user->groupids[$rec->groupid] = $rec->groupid; $ok = true; } // Subscribed to the whole forum. } else { // extra conditions for forum not separate groups or accessallgroups $groupok = $groupmode != SEPARATEGROUPS || array_key_exists($user->id, $aagusers); if (array_key_exists($user->id, $allowedusers) && $groupok) { $user->wholeforum = true; $ok = true; } } } // If this is a new user object, add it to the array provided the row was valid if ($newuser && $ok) { $users[$user->id] = $user; } } else { // This is an 'unsubscribe' request. These are only allowed // for initial-subscription, otherwise ignored if ($subscriptionoption == self::SUBSCRIPTION_INITIALLY_SUBSCRIBED && array_key_exists($user->id, $users)) { // set wholeforum = false for user (if they are in the array) $users[$rec->u_id]->unsubscribe = true; $users[$rec->u_id]->wholeforum = false; } } } $rs->close(); $allowedusers = null; // 1. loop through array and clear the discussions/groupids array if wholeforum is true. // 2. Find any user unsubscribed from initial subscribed forum. If the user has been // subscribed to discussions/groups, remove the $user->unsubscribe flag; // Otherwise remove the user from the list. foreach ($users as $key => $user) { if ($user->wholeforum) { $user->discussionids = array(); $user->groupids = array(); } // Remove discussionids for discussions that are already covered by group subscriptions // TODO if (count($user->discussionids) != 0 && count($user->groupids) != 0) { foreach ($user->discussionids as $id => $dgroupid) { if (!$dgroupid || array_key_exists($dgroupid, $user->groupids)) { unset($user->discussionids[$id]); } } } // If the user has unsubscribed from an initial subscription, then remove the entry // from the results array unless there are s subscriptions to discussions or groups if (!empty($user->unsubscribe)) { // Remove the unsubscribe as the user is likely to // subscribed to discussions or groups unset($user->unsubscribe); if (count($user->discussionids) == 0 && count($user->groupids) == 0) { unset($users[$key]); } } } // Add access-all-groups information if applicable if ($groupmode) { foreach ($users as $key => $user) { $user->accessallgroups = array_key_exists($user->id, $aagusers); } } return $users; }
/** * Load a list of users enrolled in the current course with the specified permission and group. * 0 for no group. * * @param int $currentgroup * @param bool $idsonly * @return array List of user records */ public function list_participants($currentgroup, $idsonly) { if (empty($currentgroup)) { $currentgroup = 0; } $key = $this->context->id . '-' . $currentgroup . '-' . $this->show_only_active_users(); if (!isset($this->participants[$key])) { $users = get_enrolled_users($this->context, 'mod/assign:submit', $currentgroup, 'u.*', null, null, null, $this->show_only_active_users()); $cm = $this->get_course_module(); $info = new \core_availability\info_module($cm); $users = $info->filter_user_list($users); $this->participants[$key] = $users; } if ($idsonly) { $idslist = array(); foreach ($this->participants[$key] as $id => $user) { $idslist[$id] = new stdClass(); $idslist[$id]->id = $id; } return $idslist; } return $this->participants[$key]; }
/** * Tests the filter_users (bulk checking) function. */ public function test_filter_users() { global $DB, $CFG; $this->resetAfterTest(); $CFG->enableavailability = true; // Erase static cache before test. condition::wipe_static_cache(); // Make a test course and some users. $generator = $this->getDataGenerator(); $course = $generator->create_course(); $roleids = $DB->get_records_menu('role', null, '', 'shortname, id'); $teacher = $generator->create_user(); $generator->enrol_user($teacher->id, $course->id, $roleids['teacher']); $allusers = array($teacher->id => $teacher); $students = array(); for ($i = 0; $i < 3; $i++) { $student = $generator->create_user(); $students[$i] = $student; $generator->enrol_user($student->id, $course->id, $roleids['student']); $allusers[$student->id] = $student; } $info = new \core_availability\mock_info($course); $checker = new \core_availability\capability_checker($info->get_context()); // Make test groups. $group1 = $generator->create_group(array('courseid' => $course->id)); $group2 = $generator->create_group(array('courseid' => $course->id)); $grouping1 = $generator->create_grouping(array('courseid' => $course->id)); $grouping2 = $generator->create_grouping(array('courseid' => $course->id)); groups_assign_grouping($grouping1->id, $group1->id); groups_assign_grouping($grouping2->id, $group2->id); // Make page in grouping 2. $pagegen = $generator->get_plugin_generator('mod_page'); $page = $pagegen->create_instance(array('course' => $course->id, 'groupingid' => $grouping2->id, 'availability' => '{"op":"|","show":true,"c":[{"type":"grouping","activity":true}]}')); // Assign students to groups as follows (teacher is not in a group): // 0: no groups. // 1: in group 1/grouping 1. // 2: in group 2/grouping 2. groups_add_member($group1, $students[1]); groups_add_member($group2, $students[2]); // Test specific grouping. $cond = new condition((object) array('id' => (int) $grouping1->id)); $result = array_keys($cond->filter_user_list($allusers, false, $info, $checker)); ksort($result); $this->assertEquals(array($teacher->id, $students[1]->id), $result); $result = array_keys($cond->filter_user_list($allusers, true, $info, $checker)); ksort($result); $this->assertEquals(array($teacher->id, $students[0]->id, $students[2]->id), $result); // Test course-module grouping. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($page->cmid); $info = new \core_availability\info_module($cm); $result = array_keys($info->filter_user_list($allusers, $course)); $this->assertEquals(array($teacher->id, $students[2]->id), $result); }
protected function define_execution() { global $CFG, $DB; // Note: This code runs even if availability is disabled when restoring. // That will ensure that if you later turn availability on for the site, // there will be no incorrect IDs. (It doesn't take long if the restored // data does not contain any availability information.) // Get modinfo with all data after resetting cache. rebuild_course_cache($this->get_courseid(), true); $modinfo = get_fast_modinfo($this->get_courseid()); // Update all sections that were restored. $params = array('backupid' => $this->get_restoreid(), 'itemname' => 'course_section'); $rs = $DB->get_recordset('backup_ids_temp', $params, '', 'newitemid'); $sectionsbyid = null; foreach ($rs as $rec) { if (is_null($sectionsbyid)) { $sectionsbyid = array(); foreach ($modinfo->get_section_info_all() as $section) { $sectionsbyid[$section->id] = $section; } } if (!array_key_exists($rec->newitemid, $sectionsbyid)) { // If the section was not fully restored for some reason // (e.g. due to an earlier error), skip it. $this->get_logger()->process('Section not fully restored: id ' . $rec->newitemid, backup::LOG_WARNING); continue; } $section = $sectionsbyid[$rec->newitemid]; if (!is_null($section->availability)) { $info = new \core_availability\info_section($section); $info->update_after_restore($this->get_restoreid(), $this->get_courseid(), $this->get_logger()); } } $rs->close(); // Update all modules that were restored. $params = array('backupid' => $this->get_restoreid(), 'itemname' => 'course_module'); $rs = $DB->get_recordset('backup_ids_temp', $params, '', 'newitemid'); foreach ($rs as $rec) { if (!array_key_exists($rec->newitemid, $modinfo->cms)) { // If the module was not fully restored for some reason // (e.g. due to an earlier error), skip it. $this->get_logger()->process('Module not fully restored: id ' . $rec->newitemid, backup::LOG_WARNING); continue; } $cm = $modinfo->get_cm($rec->newitemid); if (!is_null($cm->availability)) { $info = new \core_availability\info_module($cm); $info->update_after_restore($this->get_restoreid(), $this->get_courseid(), $this->get_logger()); } } $rs->close(); }
/** * @global object * @param object $choice * @param object $course * @param object $coursemodule * @param array $allresponses * * @param bool $allresponses * @return object */ function prepare_choice_show_results($choice, $course, $cm, $allresponses) { global $OUTPUT; $display = clone $choice; $display->coursemoduleid = $cm->id; $display->courseid = $course->id; if (!empty($choice->showunanswered)) { $choice->option[0] = get_string('notanswered', 'choice'); $choice->maxanswers[0] = 0; } // Remove from the list of non-respondents the users who do not have access to this activity. if (!empty($display->showunanswered) && $allresponses[0]) { $info = new \core_availability\info_module(cm_info::create($cm)); $allresponses[0] = $info->filter_user_list($allresponses[0]); } //overwrite options value; $display->options = array(); $allusers = []; foreach ($choice->option as $optionid => $optiontext) { $display->options[$optionid] = new stdClass(); $display->options[$optionid]->text = $optiontext; $display->options[$optionid]->maxanswer = $choice->maxanswers[$optionid]; if (array_key_exists($optionid, $allresponses)) { $display->options[$optionid]->user = $allresponses[$optionid]; $allusers = array_merge($allusers, array_keys($allresponses[$optionid])); } } unset($display->option); unset($display->maxanswers); $display->numberofuser = count(array_unique($allusers)); $context = context_module::instance($cm->id); $display->viewresponsecapability = has_capability('mod/choice:readresponses', $context); $display->deleterepsonsecapability = has_capability('mod/choice:deleteresponses', $context); $display->fullnamecapability = has_capability('moodle/site:viewfullnames', $context); if (empty($allresponses)) { echo $OUTPUT->heading(get_string("nousersyet"), 3, null); return false; } return $display; }