/** * Define the form - called by parent constructor */ public function definition() { global $DB; $mform = $this->_form; $params = $this->_customdata; // Instance variable is used by the form validation function. $instance = $params['instance']; $this->instance = $instance; // Get the assignment class. $assign = $params['assign']; $userlist = $params['userlist']; $usercount = 0; $usershtml = ''; $extrauserfields = get_extra_user_fields($assign->get_context()); foreach ($userlist as $userid) { if ($usercount >= 5) { $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5); break; } $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $usershtml .= $assign->get_renderer()->render(new assign_user_summary($user, $assign->get_course()->id, has_capability('moodle/site:viewfullnames', $assign->get_course_context()), $assign->is_blind_marking(), $assign->get_uniqueid_for_user($user->id), $extrauserfields, !$assign->is_active_user($userid))); $usercount += 1; } $userscount = count($userlist); $listusersmessage = get_string('grantextensionforusers', 'assign', $userscount); $mform->addElement('header', 'general', $listusersmessage); $mform->addElement('static', 'userslist', get_string('selectedusers', 'assign'), $usershtml); if ($instance->allowsubmissionsfromdate) { $mform->addElement('static', 'allowsubmissionsfromdate', get_string('allowsubmissionsfromdate', 'assign'), userdate($instance->allowsubmissionsfromdate)); } $finaldate = 0; if ($instance->duedate) { $mform->addElement('static', 'duedate', get_string('duedate', 'assign'), userdate($instance->duedate)); $finaldate = $instance->duedate; } if ($instance->cutoffdate) { $mform->addElement('static', 'cutoffdate', get_string('cutoffdate', 'assign'), userdate($instance->cutoffdate)); $finaldate = $instance->cutoffdate; } $mform->addElement('date_time_selector', 'extensionduedate', get_string('extensionduedate', 'assign'), array('optional' => true)); $mform->setDefault('extensionduedate', $finaldate); $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'userid'); $mform->setType('userid', PARAM_INT); $mform->addElement('hidden', 'selectedusers'); $mform->setType('selectedusers', PARAM_SEQUENCE); $mform->addElement('hidden', 'action', 'saveextension'); $mform->setType('action', PARAM_ALPHA); $this->add_action_buttons(true, get_string('savechanges', 'assign')); }
/** * Initialises table */ protected function init() { $tablecolumns = array('userpic', 'fullname'); $tableheaders = array(get_string('userpic'), get_string('fullnameuser')); $extrafields = get_extra_user_fields($this->get_context()); $ufields = user_picture::fields('u', $extrafields, $this->useridfield); $fields = 'c.id, c.timemodified as completed_timemodified, c.courseid, ' . $ufields; $from = '{feedback_completed} c ' . 'JOIN {user} u ON u.id = c.userid AND u.deleted = :notdeleted'; $where = 'c.anonymous_response = :anon AND c.feedback = :instance'; if ($this->feedbackstructure->get_courseid()) { $where .= ' AND c.courseid = :courseid'; } if ($this->is_downloading()) { // When downloading data: // Remove 'userpic' from downloaded data. array_shift($tablecolumns); array_shift($tableheaders); // Add all identity fields as separate columns. foreach ($extrafields as $field) { $fields .= ", u.{$field}"; $tablecolumns[] = $field; $tableheaders[] = get_user_field_name($field); } } if ($this->feedbackstructure->get_feedback()->course == SITEID && !$this->feedbackstructure->get_courseid()) { $tablecolumns[] = 'courseid'; $tableheaders[] = get_string('course'); } $tablecolumns[] = 'completed_timemodified'; $tableheaders[] = get_string('date'); $this->define_columns($tablecolumns); $this->define_headers($tableheaders); $this->sortable(true, 'lastname', SORT_ASC); $this->collapsible(true); $this->set_attribute('id', 'showentrytable'); $params = array(); $params['anon'] = FEEDBACK_ANONYMOUS_NO; $params['instance'] = $this->feedbackstructure->get_feedback()->id; $params['notdeleted'] = 0; $params['courseid'] = $this->feedbackstructure->get_courseid(); $group = groups_get_activity_group($this->feedbackstructure->get_cm(), true); if ($group) { $where .= ' AND c.userid IN (SELECT g.userid FROM {groups_members} g WHERE g.groupid = :group)'; $params['group'] = $group; } $this->set_sql($fields, $from, $where, $params); $this->set_count_sql("SELECT COUNT(c.id) FROM {$from} WHERE {$where}", $params); }
/** * Set the display options for the user-related columns in the table. * @param table_sql $table the table being constructed. */ protected function configure_user_columns($table) { $table->column_suppress('picture'); $table->column_suppress('fullname'); $extrafields = get_extra_user_fields($this->context); foreach ($extrafields as $field) { $table->column_suppress($field); } $table->column_class('picture', 'picture'); $table->column_class('lastname', 'bold'); $table->column_class('firstname', 'bold'); $table->column_class('fullname', 'bold'); }
/** * overridden constructor keeps a reference to the assignment class that is displaying this table * * @param assign $assignment The assignment class * @param int $perpage how many per page * @param string $filter The current filter * @param int $rowoffset For showing a subsequent page of results * @param bool $quickgrading Is this table wrapped in a quickgrading form? * @param string $downloadfilename */ public function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgrading, $downloadfilename = null) { global $CFG, $PAGE, $DB, $USER; parent::__construct('mod_assign_grading'); $this->is_persistent(true); $this->assignment = $assignment; // Check permissions up front. $this->hasgrantextension = has_capability('mod/assign:grantextension', $this->assignment->get_context()); $this->hasgrade = $this->assignment->can_grade(); // Check if we have the elevated view capablities to see the blind details. $this->hasviewblind = has_capability('mod/assign:viewblinddetails', $this->assignment->get_context()); foreach ($assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_grading_batch_operations() as $action => $description) { if (empty($this->plugingradingbatchoperations)) { $this->plugingradingbatchoperations[$plugin->get_type()] = array(); } $this->plugingradingbatchoperations[$plugin->get_type()][$action] = $description; } } } $this->perpage = $perpage; $this->quickgrading = $quickgrading && $this->hasgrade; $this->output = $PAGE->get_renderer('mod_assign'); $urlparams = array('action' => 'grading', 'id' => $assignment->get_course_module()->id); $url = new moodle_url($CFG->wwwroot . '/mod/assign/view.php', $urlparams); $this->define_baseurl($url); // Do some business - then set the sql. $currentgroup = groups_get_activity_group($assignment->get_course_module(), true); if ($rowoffset) { $this->rownum = $rowoffset - 1; } $users = array_keys($assignment->list_participants($currentgroup, true)); if (count($users) == 0) { // Insert a record that will never match to the sql is still valid. $users[] = -1; } $params = array(); $params['assignmentid1'] = (int) $this->assignment->get_instance()->id; $params['assignmentid2'] = (int) $this->assignment->get_instance()->id; $params['assignmentid3'] = (int) $this->assignment->get_instance()->id; $extrauserfields = get_extra_user_fields($this->assignment->get_context()); $fields = user_picture::fields('u', $extrauserfields) . ', '; $fields .= 'u.id as userid, '; $fields .= 's.status as status, '; $fields .= 's.id as submissionid, '; $fields .= 's.timecreated as firstsubmission, '; $fields .= 's.timemodified as timesubmitted, '; $fields .= 's.attemptnumber as attemptnumber, '; $fields .= 'g.id as gradeid, '; $fields .= 'g.grade as grade, '; $fields .= 'g.timemodified as timemarked, '; $fields .= 'g.timecreated as firstmarked, '; $fields .= 'uf.mailed as mailed, '; $fields .= 'uf.locked as locked, '; $fields .= 'uf.extensionduedate as extensionduedate, '; $fields .= 'uf.workflowstate as workflowstate, '; $fields .= 'uf.allocatedmarker as allocatedmarker '; $from = '{user} u LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid1 AND s.latest = 1 LEFT JOIN {assign_grades} g ON u.id = g.userid AND g.assignment = :assignmentid2 '; // For group submissions we don't immediately create an entry in the assign_submission table for each user, // instead the userid is set to 0. In this case we use a different query to retrieve the grade for the user. if ($this->assignment->get_instance()->teamsubmission) { $params['assignmentid4'] = (int) $this->assignment->get_instance()->id; $grademaxattempt = 'SELECT mxg.userid, MAX(mxg.attemptnumber) AS maxattempt FROM {assign_grades} mxg WHERE mxg.assignment = :assignmentid4 GROUP BY mxg.userid'; $from .= 'LEFT JOIN (' . $grademaxattempt . ') gmx ON u.id = gmx.userid AND g.attemptnumber = gmx.maxattempt '; } else { $from .= 'AND g.attemptnumber = s.attemptnumber '; } $from .= 'LEFT JOIN {assign_user_flags} uf ON u.id = uf.userid AND uf.assignment = :assignmentid3'; $userparams = array(); $userindex = 0; list($userwhere, $userparams) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED, 'user'); $where = 'u.id ' . $userwhere; $params = array_merge($params, $userparams); // The filters do not make sense when there are no submissions, so do not apply them. if ($this->assignment->is_any_submission_plugin_enabled()) { if ($filter == ASSIGN_FILTER_SUBMITTED) { $where .= ' AND (s.timemodified IS NOT NULL AND s.status = :submitted) '; $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED; } else { if ($filter == ASSIGN_FILTER_NOT_SUBMITTED) { $where .= ' AND (s.timemodified IS NULL OR s.status != :submitted) '; $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED; } else { if ($filter == ASSIGN_FILTER_REQUIRE_GRADING) { $where .= ' AND (s.timemodified IS NOT NULL AND s.status = :submitted AND (s.timemodified >= g.timemodified OR g.timemodified IS NULL OR g.grade IS NULL))'; $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED; } else { if (strpos($filter, ASSIGN_FILTER_SINGLE_USER) === 0) { $userfilter = (int) array_pop(explode('=', $filter)); $where .= ' AND (u.id = :userid)'; $params['userid'] = $userfilter; } } } } } if ($this->assignment->get_instance()->markingworkflow && $this->assignment->get_instance()->markingallocation) { if (has_capability('mod/assign:manageallocations', $this->assignment->get_context())) { // Check to see if marker filter is set. $markerfilter = (int) get_user_preferences('assign_markerfilter', ''); if (!empty($markerfilter)) { if ($markerfilter == ASSIGN_MARKER_FILTER_NO_MARKER) { $where .= ' AND (uf.allocatedmarker IS NULL OR uf.allocatedmarker = 0)'; } else { $where .= ' AND uf.allocatedmarker = :markerid'; $params['markerid'] = $markerfilter; } } } else { // Only show users allocated to this marker. $where .= ' AND uf.allocatedmarker = :markerid'; $params['markerid'] = $USER->id; } } if ($this->assignment->get_instance()->markingworkflow) { $workflowstates = $this->assignment->get_marking_workflow_states_for_current_user(); if (!empty($workflowstates)) { $workflowfilter = get_user_preferences('assign_workflowfilter', ''); if ($workflowfilter == ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED) { $where .= ' AND (uf.workflowstate = :workflowstate OR uf.workflowstate IS NULL OR ' . $DB->sql_isempty('assign_user_flags', 'workflowstate', true, true) . ')'; $params['workflowstate'] = $workflowfilter; } else { if (array_key_exists($workflowfilter, $workflowstates)) { $where .= ' AND uf.workflowstate = :workflowstate'; $params['workflowstate'] = $workflowfilter; } } } } $this->set_sql($fields, $from, $where, $params); if ($downloadfilename) { $this->is_downloading('csv', $downloadfilename); } $columns = array(); $headers = array(); // Select. if (!$this->is_downloading() && $this->hasgrade) { $columns[] = 'select'; $headers[] = get_string('select') . '<div class="selectall"><label class="accesshide" for="selectall">' . get_string('selectall') . '</label> <input type="checkbox" id="selectall" name="selectall" title="' . get_string('selectall') . '"/></div>'; } // User picture. if ($this->hasviewblind || !$this->assignment->is_blind_marking()) { if (!$this->is_downloading()) { $columns[] = 'picture'; $headers[] = get_string('pictureofuser'); } else { $columns[] = 'recordid'; $headers[] = get_string('recordid', 'assign'); } // Fullname. $columns[] = 'fullname'; $headers[] = get_string('fullname'); foreach ($extrauserfields as $extrafield) { $columns[] = $extrafield; $headers[] = get_user_field_name($extrafield); } } else { // Record ID. $columns[] = 'recordid'; $headers[] = get_string('recordid', 'assign'); } // Submission status. $columns[] = 'status'; $headers[] = get_string('status', 'assign'); // Team submission columns. if ($assignment->get_instance()->teamsubmission) { $columns[] = 'team'; $headers[] = get_string('submissionteam', 'assign'); } // Allocated marker. if ($this->assignment->get_instance()->markingworkflow && $this->assignment->get_instance()->markingallocation && has_capability('mod/assign:manageallocations', $this->assignment->get_context())) { // Add a column for the allocated marker. $columns[] = 'allocatedmarker'; $headers[] = get_string('marker', 'assign'); } // Grade. $columns[] = 'grade'; $headers[] = get_string('grade'); if ($this->is_downloading()) { if ($this->assignment->get_instance()->grade >= 0) { $columns[] = 'grademax'; $headers[] = get_string('maxgrade', 'assign'); } else { // This is a custom scale. $columns[] = 'scale'; $headers[] = get_string('scale', 'assign'); } if ($this->assignment->get_instance()->markingworkflow) { // Add a column for the marking workflow state. $columns[] = 'workflowstate'; $headers[] = get_string('markingworkflowstate', 'assign'); } // Add a column for the list of valid marking workflow states. $columns[] = 'gradecanbechanged'; $headers[] = get_string('gradecanbechanged', 'assign'); } if (!$this->is_downloading() && $this->hasgrade) { // We have to call this column userid so we can use userid as a default sortable column. $columns[] = 'userid'; $headers[] = get_string('edit'); } // Submission plugins. if ($assignment->is_any_submission_plugin_enabled()) { $columns[] = 'timesubmitted'; $headers[] = get_string('lastmodifiedsubmission', 'assign'); foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($this->is_downloading()) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_editor_fields() as $field => $description) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin, $field); $columns[] = $index; $headers[] = $plugin->get_name(); } } } else { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin); $columns[] = $index; $headers[] = $plugin->get_name(); } } } } // Time marked. $columns[] = 'timemarked'; $headers[] = get_string('lastmodifiedgrade', 'assign'); // Feedback plugins. foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($this->is_downloading()) { if ($plugin->is_visible() && $plugin->is_enabled()) { foreach ($plugin->get_editor_fields() as $field => $description) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin, $field); $columns[] = $index; $headers[] = $description; } } } else { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $index = 'plugin' . count($this->plugincache); $this->plugincache[$index] = array($plugin); $columns[] = $index; $headers[] = $plugin->get_name(); } } } // Exclude 'Final grade' column in downloaded grading worksheets. if (!$this->is_downloading()) { // Final grade. $columns[] = 'finalgrade'; $headers[] = get_string('finalgrade', 'grades'); } // Load the grading info for all users. $this->gradinginfo = grade_get_grades($this->assignment->get_course()->id, 'mod', 'assign', $this->assignment->get_instance()->id, $users); if (!empty($CFG->enableoutcomes) && !empty($this->gradinginfo->outcomes)) { $columns[] = 'outcomes'; $headers[] = get_string('outcomes', 'grades'); } // Set the columns. $this->define_columns($columns); $this->define_headers($headers); foreach ($extrauserfields as $extrafield) { $this->column_class($extrafield, $extrafield); } $this->no_sorting('recordid'); $this->no_sorting('finalgrade'); $this->no_sorting('userid'); $this->no_sorting('select'); $this->no_sorting('outcomes'); if ($assignment->get_instance()->teamsubmission) { $this->no_sorting('team'); } $plugincolumnindex = 0; foreach ($this->assignment->get_submission_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $submissionpluginindex = 'plugin' . $plugincolumnindex++; $this->no_sorting($submissionpluginindex); } } foreach ($this->assignment->get_feedback_plugins() as $plugin) { if ($plugin->is_visible() && $plugin->is_enabled() && $plugin->has_user_summary()) { $feedbackpluginindex = 'plugin' . $plugincolumnindex++; $this->no_sorting($feedbackpluginindex); } } // When there is no data we still want the column headers printed in the csv file. if ($this->is_downloading()) { $this->start_output(); } }
/** * Shows a form that allows the allocated marker for selected submissions to be changed. * * @param moodleform $mform Set to a grading batch operations form * @return string - the page to view after processing these actions */ private function view_batch_markingallocation($mform) { global $CFG, $DB; require_once $CFG->dirroot . '/mod/assign/batchsetallocatedmarkerform.php'; $o = ''; $submitteddata = $mform->get_data(); $users = $submitteddata->selectedusers; $userlist = explode(',', $users); $formparams = array('cm' => $this->get_course_module()->id, 'users' => $userlist, 'context' => $this->get_context()); $usershtml = ''; $usercount = 0; $extrauserfields = get_extra_user_fields($this->get_context()); foreach ($userlist as $userid) { if ($usercount >= 5) { $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5); break; } $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $usershtml .= $this->get_renderer()->render(new assign_user_summary($user, $this->get_course()->id, has_capability('moodle/site:viewfullnames', $this->get_course_context()), $this->is_blind_marking(), $this->get_uniqueid_for_user($user->id), $extrauserfields, !$this->is_active_user($userid))); $usercount += 1; } $formparams['usershtml'] = $usershtml; $markers = get_users_by_capability($this->get_context(), 'mod/assign:grade'); $markerlist = array(); foreach ($markers as $marker) { $markerlist[$marker->id] = fullname($marker); } $formparams['markers'] = $markerlist; $mform = new mod_assign_batch_set_allocatedmarker_form(null, $formparams); $o .= $this->get_renderer()->header(); $o .= $this->get_renderer()->render(new assign_form('setworkflowstate', $mform)); $o .= $this->view_footer(); $this->add_to_log('view batch set marker allocation', get_string('viewbatchmarkingallocation', 'assign')); return $o; }
/** * * Give user record from mdl_user, build an array conntains * all user details * * Warning: description file urls are 'webservice/pluginfile.php' is use. * it can be changed with $CFG->moodlewstextformatlinkstoimagesfile * * @param stdClass $user user record from mdl_user * @param stdClass $context context object * @param stdClass $course moodle course * @param array $userfields required fields * @return array|null */ function user_get_user_details($user, $course = null, array $userfields = array()) { global $USER, $DB, $CFG; require_once $CFG->dirroot . "/user/profile/lib.php"; //custom field library require_once $CFG->dirroot . "/lib/filelib.php"; // file handling on description and friends $defaultfields = user_get_default_fields(); if (empty($userfields)) { $userfields = $defaultfields; } foreach ($userfields as $thefield) { if (!in_array($thefield, $defaultfields)) { throw new moodle_exception('invaliduserfield', 'error', '', $thefield); } } // Make sure id and fullname are included if (!in_array('id', $userfields)) { $userfields[] = 'id'; } if (!in_array('fullname', $userfields)) { $userfields[] = 'fullname'; } if (!empty($course)) { $context = context_course::instance($course->id); $usercontext = context_user::instance($user->id); $canviewdetailscap = has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext); } else { $context = context_user::instance($user->id); $usercontext = $context; $canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext); } $currentuser = $user->id == $USER->id; $isadmin = is_siteadmin($USER); $showuseridentityfields = get_extra_user_fields($context); if (!empty($course)) { $canviewhiddenuserfields = has_capability('moodle/course:viewhiddenuserfields', $context); } else { $canviewhiddenuserfields = has_capability('moodle/user:viewhiddendetails', $context); } $canviewfullnames = has_capability('moodle/site:viewfullnames', $context); if (!empty($course)) { $canviewuseremail = has_capability('moodle/course:useremail', $context); } else { $canviewuseremail = false; } $cannotviewdescription = !empty($CFG->profilesforenrolledusersonly) && !$currentuser && !$DB->record_exists('role_assignments', array('userid' => $user->id)); if (!empty($course)) { $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context); } else { $canaccessallgroups = false; } if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) { // skip this user details return null; } $userdetails = array(); $userdetails['id'] = $user->id; if (($isadmin or $currentuser) and in_array('username', $userfields)) { $userdetails['username'] = $user->username; } if ($isadmin or $canviewfullnames) { if (in_array('firstname', $userfields)) { $userdetails['firstname'] = $user->firstname; } if (in_array('lastname', $userfields)) { $userdetails['lastname'] = $user->lastname; } } $userdetails['fullname'] = fullname($user); if (in_array('customfields', $userfields)) { $fields = $DB->get_recordset_sql("SELECT f.*\n FROM {user_info_field} f\n JOIN {user_info_category} c\n ON f.categoryid=c.id\n ORDER BY c.sortorder ASC, f.sortorder ASC"); $userdetails['customfields'] = array(); foreach ($fields as $field) { require_once $CFG->dirroot . '/user/profile/field/' . $field->datatype . '/field.class.php'; $newfield = 'profile_field_' . $field->datatype; $formfield = new $newfield($field->id, $user->id); if ($formfield->is_visible() and !$formfield->is_empty()) { $userdetails['customfields'][] = array('name' => $formfield->field->name, 'value' => $formfield->data, 'type' => $field->datatype, 'shortname' => $formfield->field->shortname); } } $fields->close(); // unset customfields if it's empty if (empty($userdetails['customfields'])) { unset($userdetails['customfields']); } } // profile image if (in_array('profileimageurl', $userfields)) { $profileimageurl = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f1'); $userdetails['profileimageurl'] = $profileimageurl->out(false); } if (in_array('profileimageurlsmall', $userfields)) { $profileimageurlsmall = moodle_url::make_pluginfile_url($usercontext->id, 'user', 'icon', NULL, '/', 'f2'); $userdetails['profileimageurlsmall'] = $profileimageurlsmall->out(false); } //hidden user field if ($canviewhiddenuserfields) { $hiddenfields = array(); // address, phone1 and phone2 not appears in hidden fields list // but require viewhiddenfields capability // according to user/profile.php if ($user->address && in_array('address', $userfields)) { $userdetails['address'] = $user->address; } } else { $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields)); } if ($user->phone1 && in_array('phone1', $userfields) && (in_array('phone1', $showuseridentityfields) or $canviewhiddenuserfields)) { $userdetails['phone1'] = $user->phone1; } if ($user->phone2 && in_array('phone2', $userfields) && (in_array('phone2', $showuseridentityfields) or $canviewhiddenuserfields)) { $userdetails['phone2'] = $user->phone2; } if (isset($user->description) && (!isset($hiddenfields['description']) && !$cannotviewdescription or $isadmin)) { if (in_array('description', $userfields)) { // Always return the descriptionformat if description is requested. list($userdetails['description'], $userdetails['descriptionformat']) = external_format_text($user->description, $user->descriptionformat, $usercontext->id, 'user', 'profile', null); } } if (in_array('country', $userfields) && (!isset($hiddenfields['country']) or $isadmin) && $user->country) { $userdetails['country'] = $user->country; } if (in_array('city', $userfields) && (!isset($hiddenfields['city']) or $isadmin) && $user->city) { $userdetails['city'] = $user->city; } if (in_array('url', $userfields) && $user->url && (!isset($hiddenfields['webpage']) or $isadmin)) { $url = $user->url; if (strpos($user->url, '://') === false) { $url = 'http://' . $url; } $user->url = clean_param($user->url, PARAM_URL); $userdetails['url'] = $user->url; } if (in_array('icq', $userfields) && $user->icq && (!isset($hiddenfields['icqnumber']) or $isadmin)) { $userdetails['icq'] = $user->icq; } if (in_array('skype', $userfields) && $user->skype && (!isset($hiddenfields['skypeid']) or $isadmin)) { $userdetails['skype'] = $user->skype; } if (in_array('yahoo', $userfields) && $user->yahoo && (!isset($hiddenfields['yahooid']) or $isadmin)) { $userdetails['yahoo'] = $user->yahoo; } if (in_array('aim', $userfields) && $user->aim && (!isset($hiddenfields['aimid']) or $isadmin)) { $userdetails['aim'] = $user->aim; } if (in_array('msn', $userfields) && $user->msn && (!isset($hiddenfields['msnid']) or $isadmin)) { $userdetails['msn'] = $user->msn; } if (in_array('firstaccess', $userfields) && (!isset($hiddenfields['firstaccess']) or $isadmin)) { if ($user->firstaccess) { $userdetails['firstaccess'] = $user->firstaccess; } else { $userdetails['firstaccess'] = 0; } } if (in_array('lastaccess', $userfields) && (!isset($hiddenfields['lastaccess']) or $isadmin)) { if ($user->lastaccess) { $userdetails['lastaccess'] = $user->lastaccess; } else { $userdetails['lastaccess'] = 0; } } if (in_array('email', $userfields) && ($isadmin or $currentuser or $canviewuseremail or in_array('email', $showuseridentityfields) or $user->maildisplay == 1 or $user->maildisplay == 2 and enrol_sharing_course($user, $USER))) { $userdetails['email'] = $user->email; } if (in_array('interests', $userfields) && !empty($CFG->usetags)) { require_once $CFG->dirroot . '/tag/lib.php'; if ($interests = tag_get_tags_csv('user', $user->id, TAG_RETURN_TEXT)) { $userdetails['interests'] = $interests; } } //Departement/Institution/Idnumber are not displayed on any profile, however you can get them from editing profile. if ($isadmin or $currentuser or in_array('idnumber', $showuseridentityfields)) { if (in_array('idnumber', $userfields) && $user->idnumber) { $userdetails['idnumber'] = $user->idnumber; } } if ($isadmin or $currentuser or in_array('institution', $showuseridentityfields)) { if (in_array('institution', $userfields) && $user->institution) { $userdetails['institution'] = $user->institution; } } if ($isadmin or $currentuser or in_array('department', $showuseridentityfields)) { if (in_array('department', $userfields) && isset($user->department)) { //isset because it's ok to have department 0 $userdetails['department'] = $user->department; } } if (in_array('roles', $userfields) && !empty($course)) { // not a big secret $roles = get_user_roles($context, $user->id, false); $userdetails['roles'] = array(); foreach ($roles as $role) { $userdetails['roles'][] = array('roleid' => $role->roleid, 'name' => $role->name, 'shortname' => $role->shortname, 'sortorder' => $role->sortorder); } } // If groups are in use and enforced throughout the course, then make sure we can meet in at least one course level group if (in_array('groups', $userfields) && !empty($course) && $canaccessallgroups) { $usergroups = groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name,g.description,g.descriptionformat'); $userdetails['groups'] = array(); foreach ($usergroups as $group) { list($group->description, $group->descriptionformat) = external_format_text($group->description, $group->descriptionformat, $context->id, 'group', 'description', $group->id); $userdetails['groups'][] = array('id' => $group->id, 'name' => $group->name, 'description' => $group->description, 'descriptionformat' => $group->descriptionformat); } } //list of courses where the user is enrolled if (in_array('enrolledcourses', $userfields) && !isset($hiddenfields['mycourses'])) { $enrolledcourses = array(); if ($mycourses = enrol_get_users_courses($user->id, true)) { foreach ($mycourses as $mycourse) { if ($mycourse->category) { $coursecontext = context_course::instance($mycourse->id); $enrolledcourse = array(); $enrolledcourse['id'] = $mycourse->id; $enrolledcourse['fullname'] = format_string($mycourse->fullname, true, array('context' => $coursecontext)); $enrolledcourse['shortname'] = format_string($mycourse->shortname, true, array('context' => $coursecontext)); $enrolledcourses[] = $enrolledcourse; } } $userdetails['enrolledcourses'] = $enrolledcourses; } } //user preferences if (in_array('preferences', $userfields) && $currentuser) { $preferences = array(); $userpreferences = get_user_preferences(); foreach ($userpreferences as $prefname => $prefvalue) { $preferences[] = array('name' => $prefname, 'value' => $prefvalue); } $userdetails['preferences'] = $preferences; } return $userdetails; }
/** * Shows a form that allows the allocated marker for selected submissions to be changed. * * @param moodleform $mform Set to a grading batch operations form * @return string - the page to view after processing these actions */ public function view_batch_markingallocation($mform) { global $CFG, $DB; require_once $CFG->dirroot . '/mod/assign/batchsetallocatedmarkerform.php'; $o = ''; $submitteddata = $mform->get_data(); $users = $submitteddata->selectedusers; $userlist = explode(',', $users); $formdata = array('id' => $this->get_course_module()->id, 'selectedusers' => $users); $usershtml = ''; $usercount = 0; $extrauserfields = get_extra_user_fields($this->get_context()); foreach ($userlist as $userid) { if ($usercount >= 5) { $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5); break; } $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $usershtml .= $this->get_renderer()->render(new assign_user_summary($user, $this->get_course()->id, has_capability('moodle/site:viewfullnames', $this->get_course_context()), $this->is_blind_marking(), $this->get_uniqueid_for_user($user->id), $extrauserfields, !$this->is_active_user($userid))); $usercount += 1; } $formparams = array('userscount' => count($userlist), 'usershtml' => $usershtml); list($sort, $params) = users_order_by_sql(); $markers = get_users_by_capability($this->get_context(), 'mod/assign:grade', '', $sort); $markerlist = array(); foreach ($markers as $marker) { $markerlist[$marker->id] = fullname($marker); } $formparams['markers'] = $markerlist; $mform = new mod_assign_batch_set_allocatedmarker_form(null, $formparams); $mform->set_data($formdata); // Initialises the hidden elements. $header = new assign_header($this->get_instance(), $this->get_context(), $this->show_intro(), $this->get_course_module()->id, get_string('setmarkingallocation', 'assign')); $o .= $this->get_renderer()->render($header); $o .= $this->get_renderer()->render(new assign_form('setworkflowstate', $mform)); $o .= $this->view_footer(); \mod_assign\event\batch_set_marker_allocation_viewed::create_from_assign($this)->trigger(); return $o; }
/** * Get sql and params to use to get list of users. * * @param \context $context Context of the page where the results would be shown. * @param string $search the text to search for (empty string = find all). * @param bool $count setting this to true, returns an sql to get count only instead of the complete data records. * * @return array sql and params list */ protected static function get_users_sql_and_params($context, $search = '', $count = false) { // Fields we need from the user table. $extrafields = get_extra_user_fields($context); $params = array(); if (!empty($search)) { list($filtersql, $params) = users_search_sql($search, 'u', true, $extrafields); $filtersql .= ' AND '; } else { $filtersql = ''; } $ufields = \user_picture::fields('u', $extrafields) . ',u.username'; if ($count) { $select = "SELECT COUNT(DISTINCT u.id) "; $orderby = ""; } else { $select = "SELECT DISTINCT {$ufields} "; $orderby = " ORDER BY u.lastname ASC, u.firstname ASC"; } $sql = "{$select}\n FROM {user} u\n JOIN {grade_grades_history} ggh ON u.id = ggh.userid\n JOIN {grade_items} gi ON gi.id = ggh.itemid\n WHERE {$filtersql} gi.courseid = :courseid"; $sql .= $orderby; $params['courseid'] = $context->instanceid; return array($sql, $params); }
/** * Gets an array of users for display, this includes minimal user information * as well as minimal information on the users roles, groups, and enrolments. * * @param core_enrol_renderer $renderer * @param moodle_url $pageurl * @param int $sort * @param string $direction ASC or DESC * @param int $page * @param int $perpage * @return array */ public function get_users_for_display(course_enrolment_manager $manager, $sort, $direction, $page, $perpage) { $pageurl = $manager->get_moodlepage()->url; $users = $this->get_users($sort, $direction, $page, $perpage); $now = time(); $straddgroup = get_string('addgroup', 'group'); $strunenrol = get_string('unenrol', 'enrol'); $stredit = get_string('edit'); $allroles = $this->get_all_roles(); $assignable = $this->get_assignable_roles(); $allgroups = $this->get_all_groups(); $context = $this->get_context(); $canmanagegroups = has_capability('moodle/course:managegroups', $context); $url = new moodle_url($pageurl, $this->get_url_params()); $extrafields = get_extra_user_fields($context); $enabledplugins = $this->get_enrolment_plugins(true); $userdetails = array(); foreach ($users as $user) { $details = $this->prepare_user_for_display($user, $extrafields, $now); // Roles $details['roles'] = array(); foreach ($this->get_user_roles($user->id) as $rid => $rassignable) { $unchangeable = !$rassignable; if (!is_siteadmin() and !isset($assignable[$rid])) { $unchangeable = true; } $details['roles'][$rid] = array('text' => $allroles[$rid]->localname, 'unchangeable' => $unchangeable); } // Users $usergroups = $this->get_user_groups($user->id); $details['groups'] = array(); foreach ($usergroups as $gid => $unused) { $details['groups'][$gid] = $allgroups[$gid]->name; } // Enrolments $details['enrolments'] = array(); foreach ($this->get_user_enrolments($user->id) as $ue) { if (!isset($enabledplugins[$ue->enrolmentinstance->enrol])) { $details['enrolments'][$ue->id] = array('text' => $ue->enrolmentinstancename, 'period' => null, 'dimmed' => true, 'actions' => array()); continue; } else { if ($ue->timestart and $ue->timeend) { $period = get_string('periodstartend', 'enrol', array('start' => userdate($ue->timestart), 'end' => userdate($ue->timeend))); $periodoutside = $ue->timestart && $ue->timeend && ($now < $ue->timestart || $now > $ue->timeend); } else { if ($ue->timestart) { $period = get_string('periodstart', 'enrol', userdate($ue->timestart)); $periodoutside = $ue->timestart && $now < $ue->timestart; } else { if ($ue->timeend) { $period = get_string('periodend', 'enrol', userdate($ue->timeend)); $periodoutside = $ue->timeend && $now > $ue->timeend; } else { // If there is no start or end show when user was enrolled. $period = get_string('periodnone', 'enrol', userdate($ue->timecreated)); $periodoutside = false; } } } } $details['enrolments'][$ue->id] = array('text' => $ue->enrolmentinstancename, 'period' => $period, 'dimmed' => $periodoutside or $ue->status != ENROL_USER_ACTIVE or $ue->enrolmentinstance->status != ENROL_INSTANCE_ENABLED, 'actions' => $ue->enrolmentplugin->get_user_enrolment_actions($manager, $ue)); } $userdetails[$user->id] = $details; } return $userdetails; }
/** * Builds and returns the rows that will make up the left part of the grader report * This consists of student names and icons, links to user reports and id numbers, as well * as header cells for these columns. It also includes the fillers required for the * categories displayed on the right side of the report. * @param boolean $displayaverages whether to display average rows in the table * @return array Array of html_table_row objects */ public function get_left_rows($displayaverages) { global $CFG, $USER, $OUTPUT; $rows = array(); $showuserimage = $this->get_pref('showuserimage'); $strfeedback = $this->get_lang_string("feedback"); $strgrade = $this->get_lang_string('grade'); $extrafields = get_extra_user_fields($this->context); $arrows = $this->get_sort_arrows($extrafields); $colspan = 1; if (has_capability('gradereport/' . $CFG->grade_profilereport . ':view', $this->context)) { $colspan++; } $colspan += count($extrafields); $levels = count($this->gtree->levels) - 1; for ($i = 0; $i < $levels; $i++) { $fillercell = new html_table_cell(); $fillercell->attributes['class'] = 'fixedcolumn cell topleft'; $fillercell->text = ' '; $fillercell->colspan = $colspan; $row = new html_table_row(array($fillercell)); $rows[] = $row; } $headerrow = new html_table_row(); $headerrow->attributes['class'] = 'heading'; $studentheader = new html_table_cell(); $studentheader->attributes['class'] = 'header'; $studentheader->scope = 'col'; $studentheader->header = true; $studentheader->id = 'studentheader'; if (has_capability('gradereport/' . $CFG->grade_profilereport . ':view', $this->context)) { $studentheader->colspan = 2; } $studentheader->text = $arrows['studentname']; $headerrow->cells[] = $studentheader; foreach ($extrafields as $field) { $fieldheader = new html_table_cell(); $fieldheader->attributes['class'] = 'header userfield user' . $field; $fieldheader->scope = 'col'; $fieldheader->header = true; $fieldheader->text = $arrows[$field]; $headerrow->cells[] = $fieldheader; } $rows[] = $headerrow; $rows = $this->get_left_icons_row($rows, $colspan); $rowclasses = array('even', 'odd'); $suspendedstring = null; foreach ($this->users as $userid => $user) { $userrow = new html_table_row(); $userrow->id = 'fixed_user_' . $userid; $userrow->attributes['class'] = 'r' . $this->rowcount++ . ' ' . $rowclasses[$this->rowcount % 2]; $usercell = new html_table_cell(); $usercell->attributes['class'] = 'user'; $usercell->header = true; $usercell->scope = 'row'; if ($showuserimage) { $usercell->text = $OUTPUT->user_picture($user); } $usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), fullname($user)); if (!empty($user->suspendedenrolment)) { $usercell->attributes['class'] .= ' usersuspended'; //may be lots of suspended users so only get the string once if (empty($suspendedstring)) { $suspendedstring = get_string('userenrolmentsuspended', 'grades'); } $usercell->text .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/enrolmentsuspended'), 'title' => $suspendedstring, 'alt' => $suspendedstring, 'class' => 'usersuspendedicon')); } $userrow->cells[] = $usercell; if (has_capability('gradereport/' . $CFG->grade_profilereport . ':view', $this->context)) { $userreportcell = new html_table_cell(); $userreportcell->attributes['class'] = 'userreport'; $userreportcell->header = true; $a = new stdClass(); $a->user = fullname($user); $strgradesforuser = get_string('gradesforuser', 'grades', $a); $url = new moodle_url('/grade/report/' . $CFG->grade_profilereport . '/index.php', array('userid' => $user->id, 'id' => $this->course->id)); $userreportcell->text = $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)); $userrow->cells[] = $userreportcell; } foreach ($extrafields as $field) { $fieldcell = new html_table_cell(); $fieldcell->attributes['class'] = 'header userfield user' . $field; $fieldcell->header = true; $fieldcell->scope = 'row'; $fieldcell->text = $user->{$field}; $userrow->cells[] = $fieldcell; } $rows[] = $userrow; } $rows = $this->get_left_range_row($rows, $colspan); if ($displayaverages) { $rows = $this->get_left_avg_row($rows, $colspan, true); $rows = $this->get_left_avg_row($rows, $colspan); } return $rows; }
/** * 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 booking_subscribed_teachers($course, $optionid, $id, $groupid = 0, $context = null, $fields = null) { global $CFG, $DB; if (empty($context)) { $cm = get_coursemodule_from_id('booking', $id); $context = context_module::instance($cm->id); } $extrauserfields = get_extra_user_fields($context); $allnames = user_picture::fields('u', $extrauserfields); 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"; } // only active enrolled users or everybody on the frontpage list($esql, $params) = get_enrolled_sql($context, '', $groupid, true); $params['optionid'] = $optionid; $results = $DB->get_records_sql("SELECT {$fields}\n\t\tFROM {user} u\n\t\tJOIN ({$esql}) je ON je.id = u.id\n\t\tJOIN {booking_teachers} s ON s.userid = u.id\n\t\tWHERE s.optionid = :optionid\n\t\tORDER BY u.email ASC", $params); // Guest user should never be subscribed to a forum. unset($results[$CFG->siteguest]); return $results; }
public function test_get_extra_user_fields() { global $CFG, $USER, $DB; $oldshowuseridentity = $CFG->showuseridentity; $olduser = $USER; $USER = $DB->get_record('user', array('id'=>2)); //admin // It would be really nice if there were a way to 'mock' has_capability // checks (either to return true or false) but as there is not, this // test doesn't test the capability check. Presumably, anyone running // unit tests will have the capability. $context = context_system::instance(); // No fields $CFG->showuseridentity = ''; $this->assertEquals(array(), get_extra_user_fields($context)); // One field $CFG->showuseridentity = 'frog'; $this->assertEquals(array('frog'), get_extra_user_fields($context)); // Two fields $CFG->showuseridentity = 'frog,zombie'; $this->assertEquals(array('frog', 'zombie'), get_extra_user_fields($context)); // No fields, except $CFG->showuseridentity = ''; $this->assertEquals(array(), get_extra_user_fields($context, array('frog'))); // One field $CFG->showuseridentity = 'frog'; $this->assertEquals(array(), get_extra_user_fields($context, array('frog'))); // Two fields $CFG->showuseridentity = 'frog,zombie'; $this->assertEquals(array('zombie'), get_extra_user_fields($context, array('frog'))); // As long as this test passes, the value will be set back. This is only // in-memory anyhow $CFG->showuseridentity = $oldshowuseridentity; $USER = $olduser; }
/** * Generate treeview markup * * @access public * @return string $html Markup for treeview */ public function generate_treeview() { global $CFG; // Maximum number of items to load (at any one level) // before giving up and suggesting search instead $maxitems = DIALOG_MAXITEMS; // Check if user has capability to view emails. $canviewemail = in_array('email', get_extra_user_fields(context_system::instance())); $html = ''; //$html .= !$this->show_treeview_only ? '<div class="treeview-wrapper dialog-nobind" id="d" style="height:auto;">' : ''; $show_root = $this->_show_treeview_root(); $html .= $show_root ? '<ul class="treeview filetree picker">' : ''; if (is_array($this->items) && !empty($this->items)) { $total = count($this->items); $count = 0; if ($total > $maxitems) { $html .= '<li class="last"><span class="empty">'; $html .= get_string('error:morethanxitemsatthislevel', 'local_core', $maxitems); $html .= ' <a href="#search-tab" onclick="$(\'#dialog-tabs\').tabs(\'select\', 1);return false;">'; $html .= get_string('trysearchinginstead', 'local_core'); $html .= '</a>'; $html .= '</span></li>'.PHP_EOL; } else { // Loop through elements foreach ($this->items as $element) { ++$count; // Initialise class vars $li_class = ''; $div_class = ''; $span_class = ''; // If last element if ($count == $total) { $li_class .= ' last'; } // If element has children if (array_key_exists($element->id, $this->parent_items)) { $li_class .= ' expandable'; $div_class .= ' hitarea expandable-hitarea'; $span_class .= ' folder'; if ($count == $total) { $li_class .= ' lastExpandable'; $div_class .= ' lastExpandable-hitarea'; } } // Make disabled elements non-draggable and greyed out if (array_key_exists($element->id, $this->disabled_items)){ $span_class .= ' unclickable'; } else { $span_class .= ' clickable'; } $html .= '<li class="'.trim($li_class).'" id="item_list_'.$element->id.'">'; $html .= '<div class="'.trim($div_class).'"></div>'; $html .= '<span id="item_'.$element->id.'" class="'.trim($span_class).'">'; // Grab item display name if (isset($element->fullname)) { if (isset($element->email) && $canviewemail) { $displayname = get_string('assignindividual', 'local_program', $element); } else { $displayname = $element->fullname; } } elseif (isset($element->name)) { $displayname = $element->name; } else { $displayname = ''; } $html .= '<a href="#"'; if (!empty($element->hover)) { $html .= ' title="'.format_string($element->hover).'"'; } $html .= '>'; $html .= format_string($displayname); $html .= '</a>'; //$html .= '<span class="deletebutton">delete</span>'; $html .= '</span>'; if ($div_class !== '') { $html .= '<ul style="display: none;"></ul>'; } $html .= '</li>'.PHP_EOL; } } } else { $html .= '<li class="last"><span class="empty">'; $html .= get_string($this->string_nothingtodisplay, $this->lang_file); $html .= '</span></li>'.PHP_EOL; } $html .= $show_root ? '</ul>' : ''; //$html .= !$this->show_treeview_only ? '</div>' : ''; return $html; }
/** * Upload files and send them to multiple users. * * @param array $users - An array of user ids * @return string - The response html */ public function view_batch_upload_files($users) { global $CFG, $DB, $USER; require_capability('mod/sepl:grade', $this->seplment->get_context()); require_once $CFG->dirroot . '/mod/sepl/feedback/file/batchuploadfilesform.php'; require_once $CFG->dirroot . '/mod/sepl/renderable.php'; $formparams = array('cm' => $this->seplment->get_course_module()->id, 'users' => $users, 'context' => $this->seplment->get_context()); $usershtml = ''; $usercount = 0; foreach ($users as $userid) { if ($usercount >= ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS) { $moreuserscount = count($users) - ASSIGNFEEDBACK_FILE_MAXSUMMARYUSERS; $usershtml .= get_string('moreusers', 'seplfeedback_file', $moreuserscount); break; } $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $usersummary = new sepl_user_summary($user, $this->seplment->get_course()->id, has_capability('moodle/site:viewfullnames', $this->seplment->get_course_context()), $this->seplment->is_blind_marking(), $this->seplment->get_uniqueid_for_user($user->id), get_extra_user_fields($this->seplment->get_context())); $usershtml .= $this->seplment->get_renderer()->render($usersummary); $usercount += 1; } $formparams['usershtml'] = $usershtml; $mform = new seplfeedback_file_batch_upload_files_form(null, $formparams); if ($mform->is_cancelled()) { redirect(new moodle_url('view.php', array('id' => $this->seplment->get_course_module()->id, 'action' => 'grading'))); return; } else { if ($data = $mform->get_data()) { // Copy the files from the draft area to a temporary import area. $data = file_postupdate_standard_filemanager($data, 'files', $this->get_file_options(), $this->seplment->get_context(), 'seplfeedback_file', ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, $USER->id); $fs = get_file_storage(); // Now copy each of these files to the users feedback file area. foreach ($users as $userid) { $grade = $this->seplment->get_user_grade($userid, true); $this->seplment->notify_grade_modified($grade); $this->copy_area_files($fs, $this->seplment->get_context()->id, 'seplfeedback_file', ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, $USER->id, $this->seplment->get_context()->id, 'seplfeedback_file', ASSIGNFEEDBACK_FILE_FILEAREA, $grade->id); $filefeedback = $this->get_file_feedback($grade->id); if ($filefeedback) { $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); $DB->update_record('seplfeedback_file', $filefeedback); } else { $filefeedback = new stdClass(); $filefeedback->numfiles = $this->count_files($grade->id, ASSIGNFEEDBACK_FILE_FILEAREA); $filefeedback->grade = $grade->id; $filefeedback->seplment = $this->seplment->get_instance()->id; $DB->insert_record('seplfeedback_file', $filefeedback); } } // Now delete the temporary import area. $fs->delete_area_files($this->seplment->get_context()->id, 'seplfeedback_file', ASSIGNFEEDBACK_FILE_BATCH_FILEAREA, $USER->id); redirect(new moodle_url('view.php', array('id' => $this->seplment->get_course_module()->id, 'action' => 'grading'))); return; } else { $header = new sepl_header($this->seplment->get_instance(), $this->seplment->get_context(), false, $this->seplment->get_course_module()->id, get_string('batchuploadfiles', 'seplfeedback_file')); $o = ''; $o .= $this->seplment->get_renderer()->render($header); $o .= $this->seplment->get_renderer()->render(new sepl_form('batchuploadfiles', $mform)); $o .= $this->seplment->get_renderer()->render_footer(); } } return $o; }
function mod_stopwatch_get_all_users(cm_info $cm, $stopwatch) { global $DB; $context = context_module::instance($cm->id); list($sql, $params) = get_enrolled_sql($context, 'mod/stopwatch:submit'); $extrauserfields = get_extra_user_fields($context); $fields = user_picture::fields('u', $extrauserfields, 'userid'); $sql = "SELECT {$fields}, s.id, s.duration, s.timecreated, s.grade, s.timegraded\n FROM ({$sql}) e\n JOIN {user} u ON e.id = u.id\n LEFT JOIN {stopwatch_user} s ON e.id = s.userid AND\n s.courseid = :courseid AND s.stopwatchid = :stopwatchid"; $params['courseid'] = $cm->course; $params['stopwatchid'] = $stopwatch->id; return $DB->get_records_sql($sql, $params); }
/** * displays the full report * @param stdClass $scorm full SCORM object * @param stdClass $cm - full course_module object * @param stdClass $course - full course object * @param string $download - type of download being requested */ function display($scorm, $cm, $course, $download) { global $CFG, $DB, $OUTPUT, $PAGE; $contextmodule = get_context_instance(CONTEXT_MODULE, $cm->id); $action = optional_param('action', '', PARAM_ALPHA); $attemptids = optional_param_array('attemptid', array(), PARAM_RAW); $attemptsmode = optional_param('attemptsmode', SCORM_REPORT_ATTEMPTS_ALL_STUDENTS, PARAM_INT); $PAGE->set_url(new moodle_url($PAGE->url, array('attemptsmode' => $attemptsmode))); if ($action == 'delete' && has_capability('mod/scorm:deleteresponses', $contextmodule) && confirm_sesskey()) { if (scorm_delete_responses($attemptids, $scorm)) { //delete responses. add_to_log($course->id, 'scorm', 'delete attempts', 'report.php?id=' . $cm->id, implode(",", $attemptids), $cm->id); echo $OUTPUT->notification(get_string('scormresponsedeleted', 'scorm'), 'notifysuccess'); } } // find out current groups mode $currentgroup = groups_get_activity_group($cm, true); // detailed report $mform = new mod_scorm_report_interactions_settings($PAGE->url, compact('currentgroup')); if ($fromform = $mform->get_data()) { $pagesize = $fromform->pagesize; $includeqtext = $fromform->qtext; $includeresp = $fromform->resp; $includeright = $fromform->right; set_user_preference('scorm_report_pagesize', $pagesize); set_user_preference('scorm_report_interactions_qtext', $includeqtext); set_user_preference('scorm_report_interactions_resp', $includeresp); set_user_preference('scorm_report_interactions_right', $includeright); } else { $pagesize = get_user_preferences('scorm_report_pagesize', 0); $includeqtext = get_user_preferences('scorm_report_interactions_qtext', 0); $includeresp = get_user_preferences('scorm_report_interactions_resp', 1); $includeright = get_user_preferences('scorm_report_interactions_right', 0); } if ($pagesize < 1) { $pagesize = SCORM_REPORT_DEFAULT_PAGE_SIZE; } // select group menu $displayoptions = array(); $displayoptions['attemptsmode'] = $attemptsmode; $displayoptions['qtext'] = $includeqtext; $displayoptions['resp'] = $includeresp; $displayoptions['right'] = $includeright; $mform->set_data($displayoptions + array('pagesize' => $pagesize)); if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used if (!$download) { groups_print_activity_menu($cm, new moodle_url($PAGE->url, $displayoptions)); } } $formattextoptions = array('context' => get_context_instance(CONTEXT_COURSE, $course->id)); // We only want to show the checkbox to delete attempts // if the user has permissions and if the report mode is showing attempts. $candelete = has_capability('mod/scorm:deleteresponses', $contextmodule) && ($attemptsmode != SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO); // select the students $nostudents = false; if (empty($currentgroup)) { // all users who can attempt scoes if (!$students = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', '', '', '', '', '', '', false)) { echo $OUTPUT->notification(get_string('nostudentsyet')); $nostudents = true; $allowedlist = ''; } else { $allowedlist = array_keys($students); } } else { // all users who can attempt scoes and who are in the currently selected group if (!$groupstudents = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', '', '', '', '', $currentgroup, '', false)) { echo $OUTPUT->notification(get_string('nostudentsingroup')); $nostudents = true; $groupstudents = array(); } $allowedlist = array_keys($groupstudents); } if ( !$nostudents ) { // Now check if asked download of data $coursecontext = context_course::instance($course->id); if ($download) { $filename = clean_filename("$course->shortname ".format_string($scorm->name, true,$formattextoptions)); } // Define table columns $columns = array(); $headers = array(); if (!$download && $candelete) { $columns[] = 'checkbox'; $headers[] = null; } if (!$download && $CFG->grade_report_showuserimage) { $columns[] = 'picture'; $headers[] = ''; } $columns[] = 'fullname'; $headers[] = get_string('name'); $extrafields = get_extra_user_fields($coursecontext); foreach ($extrafields as $field) { $columns[] = $field; $headers[] = get_user_field_name($field); } $columns[] = 'attempt'; $headers[] = get_string('attempt', 'scorm'); $columns[] = 'start'; $headers[] = get_string('started', 'scorm'); $columns[] = 'finish'; $headers[] = get_string('last', 'scorm'); $columns[] = 'score'; $headers[] = get_string('score', 'scorm'); $scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id'); foreach ($scoes as $sco) { if ($sco->launch != '') { $columns[] = 'scograde'.$sco->id; $headers[] = format_string($sco->title,'',$formattextoptions); } } $params = array(); list($usql, $params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED); // Construct the SQL $select = 'SELECT DISTINCT '.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, '; $select .= 'st.scormid AS scormid, st.attempt AS attempt, ' . 'u.id AS userid, u.idnumber, u.firstname, u.lastname, u.picture, u.imagealt, u.email'. get_extra_user_fields_sql($coursecontext, 'u', '', array('idnumber')) . ' '; // This part is the same for all cases - join users and scorm_scoes_track tables $from = 'FROM {user} u '; $from .= 'LEFT JOIN {scorm_scoes_track} st ON st.userid = u.id AND st.scormid = '.$scorm->id; switch ($attemptsmode) { case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH: // Show only students with attempts $where = ' WHERE u.id ' .$usql. ' AND st.userid IS NOT NULL'; break; case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO: // Show only students without attempts $where = ' WHERE u.id ' .$usql. ' AND st.userid IS NULL'; break; case SCORM_REPORT_ATTEMPTS_ALL_STUDENTS: // Show all students with or without attempts $where = ' WHERE u.id ' .$usql. ' AND (st.userid IS NOT NULL OR st.userid IS NULL)'; break; } $countsql = 'SELECT COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').')) AS nbresults, '; $countsql .= 'COUNT(DISTINCT('.$DB->sql_concat('u.id', '\'#\'', 'st.attempt').')) AS nbattempts, '; $countsql .= 'COUNT(DISTINCT(u.id)) AS nbusers '; $countsql .= $from.$where; $attempts = $DB->get_records_sql($select.$from.$where, $params); $questioncount = get_scorm_question_count($scorm->id); for($id = 0; $id < $questioncount; $id++) { if ($displayoptions['qtext']) { $columns[] = 'question' . $id; $headers[] = get_string('questionx', 'scormreport_interactions', $id); } if ($displayoptions['resp']) { $columns[] = 'response' . $id; $headers[] = get_string('responsex', 'scormreport_interactions', $id); } if ($displayoptions['right']) { $columns[] = 'right' . $id; $headers[] = get_string('rightanswerx', 'scormreport_interactions', $id); } } if (!$download) { $table = new flexible_table('mod-scorm-report'); $table->define_columns($columns); $table->define_headers($headers); $table->define_baseurl($PAGE->url); $table->sortable(true); $table->collapsible(true); // This is done to prevent redundant data, when a user has multiple attempts $table->column_suppress('picture'); $table->column_suppress('fullname'); foreach ($extrafields as $field) { $table->column_suppress($field); } $table->no_sorting('start'); $table->no_sorting('finish'); $table->no_sorting('score'); foreach ($scoes as $sco) { if ($sco->launch != '') { $table->no_sorting('scograde'.$sco->id); } } $table->column_class('picture', 'picture'); $table->column_class('fullname', 'bold'); $table->column_class('score', 'bold'); $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'attempts'); $table->set_attribute('class', 'generaltable generalbox'); // Start working -- this is necessary as soon as the niceties are over $table->setup(); } else if ($download == 'ODS') { require_once("$CFG->libdir/odslib.class.php"); $filename .= ".ods"; // Creating a workbook $workbook = new MoodleODSWorkbook("-"); // Sending HTTP headers $workbook->send($filename); // Creating the first worksheet $sheettitle = get_string('report', 'scorm'); $myxls =& $workbook->add_worksheet($sheettitle); // format types $format =& $workbook->add_format(); $format->set_bold(0); $formatbc =& $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb =& $workbook->add_format(); $formatb->set_bold(1); $formaty =& $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc =& $workbook->add_format(); $formatc->set_align('center'); $formatr =& $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg =& $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); // Here starts workshhet headers $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else if ($download =='Excel') { require_once("$CFG->libdir/excellib.class.php"); $filename .= ".xls"; // Creating a workbook $workbook = new MoodleExcelWorkbook("-"); // Sending HTTP headers $workbook->send($filename); // Creating the first worksheet $sheettitle = get_string('report', 'scorm'); $myxls =& $workbook->add_worksheet($sheettitle); // format types $format =& $workbook->add_format(); $format->set_bold(0); $formatbc =& $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb =& $workbook->add_format(); $formatb->set_bold(1); $formaty =& $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc =& $workbook->add_format(); $formatc->set_align('center'); $formatr =& $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg =& $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else if ($download == 'CSV') { $filename .= ".txt"; header("Content-Type: application/download\n"); header("Content-Disposition: attachment; filename=\"$filename\""); header("Expires: 0"); header("Cache-Control: must-revalidate,post-check=0,pre-check=0"); header("Pragma: public"); echo implode("\t", $headers)." \n"; } if (!$download) { $sort = $table->get_sql_sort(); } else { $sort = ''; } // Fix some wired sorting if (empty($sort)) { $sort = ' ORDER BY uniqueid'; } else { $sort = ' ORDER BY '.$sort; } if (!$download) { // Add extra limits due to initials bar list($twhere, $tparams) = $table->get_sql_where(); if ($twhere) { $where .= ' AND '.$twhere; //initial bar $params = array_merge($params, $tparams); } if (!empty($countsql)) { $count = $DB->get_record_sql($countsql,$params); $totalinitials = $count->nbresults; if ($twhere) { $countsql .= ' AND '.$twhere; } $count = $DB->get_record_sql($countsql, $params); $total = $count->nbresults; } $table->pagesize($pagesize, $total); echo '<div class="quizattemptcounts">'; if ( $count->nbresults == $count->nbattempts ) { echo get_string('reportcountattempts', 'scorm', $count); } else if ( $count->nbattempts>0 ) { echo get_string('reportcountallattempts', 'scorm', $count); } else { echo $count->nbusers.' '.get_string('users'); } echo '</div>'; } // Fetch the attempts if (!$download) { $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params, $table->get_page_start(), $table->get_page_size()); echo '<div id="scormtablecontainer">'; if ($candelete) { // Start form $strreallydel = addslashes_js(get_string('deleteattemptcheck', 'scorm')); echo '<form id="attemptsform" method="post" action="' . $PAGE->url->out(false) . '" onsubmit="return confirm(\''.$strreallydel.'\');">'; echo '<input type="hidden" name="action" value="delete"/>'; echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; echo '<div style="display: none;">'; echo html_writer::input_hidden_params($PAGE->url); echo '</div>'; echo '<div>'; } $table->initialbars($totalinitials>20); // Build table rows } else { $attempts = $DB->get_records_sql($select.$from.$where.$sort, $params); } if ($attempts) { foreach ($attempts as $scouser) { $row = array(); if (!empty($scouser->attempt)) { $timetracks = scorm_get_sco_runtime($scorm->id, false, $scouser->userid, $scouser->attempt); } else { $timetracks = ''; } if (in_array('checkbox', $columns)) { if ($candelete && !empty($timetracks->start)) { $row[] = '<input type="checkbox" name="attemptid[]" value="'. $scouser->userid . ':' . $scouser->attempt . '" />'; } else if ($candelete) { $row[] = ''; } } if (in_array('picture', $columns)) { $user = (object)array( 'id'=>$scouser->userid, 'picture'=>$scouser->picture, 'imagealt'=>$scouser->imagealt, 'email'=>$scouser->email, 'firstname'=>$scouser->firstname, 'lastname'=>$scouser->lastname); $row[] = $OUTPUT->user_picture($user, array('courseid'=>$course->id)); } if (!$download) { $row[] = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$scouser->userid.'&course='.$course->id.'">'.fullname($scouser).'</a>'; } else { $row[] = fullname($scouser); } foreach ($extrafields as $field) { $row[] = s($scouser->{$field}); } if (empty($timetracks->start)) { $row[] = '-'; $row[] = '-'; $row[] = '-'; $row[] = '-'; } else { if (!$download) { $row[] = '<a href="userreport.php?a='.$scorm->id.'&user='******'&attempt='.$scouser->attempt.'">'.$scouser->attempt.'</a>'; } else { $row[] = $scouser->attempt; } if ($download =='ODS' || $download =='Excel' ) { $row[] = userdate($timetracks->start, get_string("strftimedatetime", "langconfig")); } else { $row[] = userdate($timetracks->start); } if ($download =='ODS' || $download =='Excel' ) { $row[] = userdate($timetracks->finish, get_string('strftimedatetime', 'langconfig')); } else { $row[] = userdate($timetracks->finish); } $row[] = scorm_grade_user_attempt($scorm, $scouser->userid, $scouser->attempt); } // print out all scores of attempt foreach ($scoes as $sco) { if ($sco->launch != '') { if ($trackdata = scorm_get_tracks($sco->id, $scouser->userid, $scouser->attempt)) { if ($trackdata->status == '') { $trackdata->status = 'notattempted'; } $strstatus = get_string($trackdata->status, 'scorm'); // if raw score exists, print it if ($trackdata->score_raw != '') { $score = $trackdata->score_raw; // add max score if it exists if ($scorm->version == 'SCORM_1.3') { $maxkey = 'cmi.score.max'; } else { $maxkey = 'cmi.core.score.max'; } if (isset($trackdata->$maxkey)) { $score .= '/'.$trackdata->$maxkey; } // else print out status } else { $score = $strstatus; } if (!$download) { $row[] = '<img src="'.$OUTPUT->pix_url($trackdata->status, 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" /><br/> <a href="userreport.php?b='.$sco->id.'&user='******'&attempt='.$scouser->attempt. '" title="'.get_string('details', 'scorm').'">'.$score.'</a>'; } else { $row[] = $score; } // interaction data $i=0; $element='cmi.interactions_'.$i.'.id'; while(isset($trackdata->$element)) { if ($displayoptions['qtext']) { $element='cmi.interactions_'.$i.'.id'; if (isset($trackdata->$element)) { $row[] = s($trackdata->$element); } else { $row[] = ' '; } } if ($displayoptions['resp']) { $element='cmi.interactions_'.$i.'.student_response'; if (isset($trackdata->$element)) { $row[] = s($trackdata->$element); } else { $row[] = ' '; } } if ($displayoptions['right']) { $j=0; $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern'; $rightans = ''; if (isset($trackdata->$element)) { while(isset($trackdata->$element)) { if($j>0) { $rightans .= ','; } $rightans .= s($trackdata->$element); $j++; $element = 'cmi.interactions_'.$i.'.correct_responses_'.$j.'.pattern'; } $row[] = $rightans; } else { $row[] = ' '; } } $i++; $element = 'cmi.interactions_'.$i.'.id'; } //---end of interaction data*/ } else { // if we don't have track data, we haven't attempted yet $strstatus = get_string('notattempted', 'scorm'); if (!$download) { $row[] = '<img src="'.$OUTPUT->pix_url('notattempted', 'scorm').'" alt="'.$strstatus.'" title="'.$strstatus.'" /><br/>'.$strstatus; } else { $row[] = $strstatus; } } } } if (!$download) { $table->add_data($row); } else if ($download == 'Excel' or $download == 'ODS') { $colnum = 0; foreach ($row as $item) { $myxls->write($rownum, $colnum, $item, $format); $colnum++; } $rownum++; } else if ($download == 'CSV') { $text = implode("\t", $row); echo $text." \n"; } } if (!$download) { $table->finish_output(); if ($candelete) { echo '<table id="commands">'; echo '<tr><td>'; echo '<a href="javascript:select_all_in(\'DIV\', null, \'scormtablecontainer\');">'. get_string('selectall', 'scorm').'</a> / '; echo '<a href="javascript:deselect_all_in(\'DIV\', null, \'scormtablecontainer\');">'. get_string('selectnone', 'scorm').'</a> '; echo ' '; echo '<input type="submit" value="'.get_string('deleteselected', 'quiz_overview').'"/>'; echo '</td></tr></table>'; // Close form echo '</div>'; echo '</form>'; } echo '</div>'; if (!empty($attempts)) { echo '<table class="boxaligncenter"><tr>'; echo '<td>'; echo $OUTPUT->single_button(new moodle_url($PAGE->url, array('download'=>'ODS') + $displayoptions), get_string('downloadods')); echo "</td>\n"; echo '<td>'; echo $OUTPUT->single_button(new moodle_url($PAGE->url, array('download'=>'Excel') + $displayoptions), get_string('downloadexcel')); echo "</td>\n"; echo '<td>'; echo $OUTPUT->single_button(new moodle_url($PAGE->url, array('download'=>'CSV') + $displayoptions), get_string('downloadtext')); echo "</td>\n"; echo "<td>"; echo "</td>\n"; echo '</tr></table>'; } } } else { if ($candelete && !$download) { echo '</div>'; echo '</form>'; $table->finish_output(); } echo '</div>'; } // Show preferences form irrespective of attempts are there to report or not if (!$download) { $mform->set_data(compact('detailedrep', 'pagesize', 'attemptsmode')); $mform->display(); } if ($download == 'Excel' or $download == 'ODS') { $workbook->close(); exit; } else if ($download == 'CSV') { exit; } } else { echo $OUTPUT->notification(get_string('noactivity', 'scorm')); } }// function ends
/** * Display all the submissions ready for grading * * @global object * @global object * @global object * @global object * @param string $message * @return bool|void */ function display_submissions($message = '') { global $CFG, $DB, $USER, $DB, $OUTPUT, $PAGE; require_once $CFG->libdir . '/gradelib.php'; /* first we check to see if the form has just been submitted * to request user_preference updates */ $filters = array(self::FILTER_ALL => get_string('all'), self::FILTER_REQUIRE_GRADING => get_string('requiregrading', 'assignment')); $updatepref = optional_param('updatepref', 0, PARAM_BOOL); if ($updatepref) { $perpage = optional_param('perpage', 10, PARAM_INT); $perpage = $perpage <= 0 ? 10 : $perpage; $filter = optional_param('filter', 0, PARAM_INT); set_user_preference('assignment_perpage', $perpage); set_user_preference('assignment_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL)); set_user_preference('assignment_filter', $filter); } /* next we get perpage and quickgrade (allow quick grade) params * from database */ $perpage = get_user_preferences('assignment_perpage', 10); $quickgrade = get_user_preferences('assignment_quickgrade', 0) && $this->quickgrade_mode_allowed(); $filter = get_user_preferences('assignment_filter', 0); $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id); if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) { $uses_outcomes = true; } else { $uses_outcomes = false; } $page = optional_param('page', 0, PARAM_INT); $strsaveallfeedback = get_string('saveallfeedback', 'assignment'); /// Some shortcuts to make the code read better $course = $this->course; $assignment = $this->assignment; $cm = $this->cm; $hassubmission = false; // reset filter to all for offline assignment only. if ($assignment->assignmenttype == 'offline') { if ($filter == self::FILTER_SUBMITTED) { $filter = self::FILTER_ALL; } } else { $filters[self::FILTER_SUBMITTED] = get_string('submitted', 'assignment'); } $tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id=' . $this->cm->id, $this->assignment->id, $this->cm->id); $PAGE->set_title(format_string($this->assignment->name, true)); $PAGE->set_heading($this->course->fullname); echo $OUTPUT->header(); echo '<div class="usersubmissions">'; //hook to allow plagiarism plugins to update status/print links. echo plagiarism_update_status($this->course, $this->cm); $course_context = get_context_instance(CONTEXT_COURSE, $course->id); if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) { echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">' . get_string('seeallcoursegrades', 'grades') . '</a></div>'; } if (!empty($message)) { echo $message; // display messages here if any } $context = get_context_instance(CONTEXT_MODULE, $cm->id); /// Check to see if groups are being used in this assignment /// find out current groups mode $groupmode = groups_get_activity_groupmode($cm); $currentgroup = groups_get_activity_group($cm, true); groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id); /// Print quickgrade form around the table if ($quickgrade) { $formattrs = array(); $formattrs['action'] = new moodle_url('/mod/assignment/submissions.php'); $formattrs['id'] = 'fastg'; $formattrs['method'] = 'post'; echo html_writer::start_tag('form', $formattrs); echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'id', 'value' => $this->cm->id)); echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'mode', 'value' => 'fastgrade')); echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'page', 'value' => $page)); echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); } /// Get all ppl that are allowed to submit assignments list($esql, $params) = get_enrolled_sql($context, 'mod/assignment:submit', $currentgroup); if ($filter == self::FILTER_ALL) { $sql = "SELECT u.id FROM {user} u " . "LEFT JOIN ({$esql}) eu ON eu.id=u.id " . "WHERE u.deleted = 0 AND eu.id=u.id "; } else { $wherefilter = ' AND s.assignment = ' . $this->assignment->id; $assignmentsubmission = "LEFT JOIN {assignment_submissions} s ON (u.id = s.userid) "; if ($filter == self::FILTER_SUBMITTED) { $wherefilter .= ' AND s.timemodified > 0 '; } else { if ($filter == self::FILTER_REQUIRE_GRADING && $assignment->assignmenttype != 'offline') { $wherefilter .= ' AND s.timemarked < s.timemodified '; } else { // require grading for offline assignment $assignmentsubmission = ""; $wherefilter = ""; } } $sql = "SELECT u.id FROM {user} u " . "LEFT JOIN ({$esql}) eu ON eu.id=u.id " . $assignmentsubmission . "WHERE u.deleted = 0 AND eu.id=u.id " . $wherefilter; } $users = $DB->get_records_sql($sql, $params); if (!empty($users)) { if ($assignment->assignmenttype == 'offline' && $filter == self::FILTER_REQUIRE_GRADING) { //remove users who has submitted their assignment foreach ($this->get_submissions() as $submission) { if (array_key_exists($submission->userid, $users)) { unset($users[$submission->userid]); } } } $users = array_keys($users); } // if groupmembersonly used, remove users who are not in any group if ($users and !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)); } } $extrafields = get_extra_user_fields($context); $tablecolumns = array_merge(array('picture', 'fullname'), $extrafields, array('grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade')); if ($uses_outcomes) { $tablecolumns[] = 'outcome'; // no sorting based on outcomes column } $extrafieldnames = array(); foreach ($extrafields as $field) { $extrafieldnames[] = get_user_field_name($field); } $tableheaders = array_merge(array('', get_string('fullnameuser')), $extrafieldnames, array(get_string('grade'), get_string('comment', 'assignment'), get_string('lastmodified') . ' (' . get_string('submission', 'assignment') . ')', get_string('lastmodified') . ' (' . get_string('grade') . ')', get_string('status'), get_string('finalgrade', 'grades'))); if ($uses_outcomes) { $tableheaders[] = get_string('outcome', 'grades'); } require_once $CFG->libdir . '/tablelib.php'; $table = new flexible_table('mod-assignment-submissions'); $table->define_columns($tablecolumns); $table->define_headers($tableheaders); $table->define_baseurl($CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id . '&currentgroup=' . $currentgroup); $table->sortable(true, 'lastname'); //sorted by lastname by default $table->collapsible(true); $table->initialbars(true); $table->column_suppress('picture'); $table->column_suppress('fullname'); $table->column_class('picture', 'picture'); $table->column_class('fullname', 'fullname'); foreach ($extrafields as $field) { $table->column_class($field, $field); } $table->column_class('grade', 'grade'); $table->column_class('submissioncomment', 'comment'); $table->column_class('timemodified', 'timemodified'); $table->column_class('timemarked', 'timemarked'); $table->column_class('status', 'status'); $table->column_class('finalgrade', 'finalgrade'); if ($uses_outcomes) { $table->column_class('outcome', 'outcome'); } $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'attempts'); $table->set_attribute('class', 'submissions'); $table->set_attribute('width', '100%'); $table->no_sorting('finalgrade'); $table->no_sorting('outcome'); $table->text_sorting('submissioncomment'); // Start working -- this is necessary as soon as the niceties are over $table->setup(); /// Construct the SQL list($where, $params) = $table->get_sql_where(); if ($where) { $where .= ' AND '; } if ($filter == self::FILTER_SUBMITTED) { $where .= 's.timemodified > 0 AND '; } else { if ($filter == self::FILTER_REQUIRE_GRADING) { $where = ''; if ($assignment->assignmenttype != 'offline') { $where .= 's.timemarked < s.timemodified AND '; } } } if ($sort = $table->get_sql_sort()) { $sort = ' ORDER BY ' . $sort; } $ufields = user_picture::fields('u', $extrafields); if (!empty($users)) { $select = "SELECT {$ufields},\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) . ') '; $ausers = $DB->get_records_sql($select . $sql . $sort, $params, $table->get_page_start(), $table->get_page_size()); $table->pagesize($perpage, count($users)); ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next $offset = $page * $perpage; $strupdate = get_string('update'); $strgrade = get_string('grade'); $strview = get_string('view'); $grademenu = make_grades_menu($this->assignment->grade); if ($ausers !== false) { $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers)); $endposition = $offset + $perpage; $currentposition = 0; foreach ($ausers as $auser) { if ($currentposition == $offset && $offset < $endposition) { $rowclass = null; $final_grade = $grading_info->items[0]->grades[$auser->id]; $grademax = $grading_info->items[0]->grademax; $final_grade->formatted_grade = round($final_grade->grade, 2) . ' / ' . round($grademax, 2); $locked_overridden = 'locked'; if ($final_grade->overridden) { $locked_overridden = 'overridden'; } // TODO add here code if advanced grading grade must be reviewed => $auser->status=0 $picture = $OUTPUT->user_picture($auser); if (empty($auser->submissionid)) { $auser->grade = -1; //no submission yet } if (!empty($auser->submissionid)) { $hassubmission = true; ///Prints student answer and student modified date ///attach file or print link to student answer, depending on the type of the assignment. ///Refer to print_student_answer in inherited classes. if ($auser->timemodified > 0) { $studentmodifiedcontent = $this->print_student_answer($auser->id) . userdate($auser->timemodified); if ($assignment->timedue && $auser->timemodified > $assignment->timedue && $this->supports_lateness()) { $studentmodifiedcontent .= $this->display_lateness($auser->timemodified); $rowclass = 'late'; } } else { $studentmodifiedcontent = ' '; } $studentmodified = html_writer::tag('div', $studentmodifiedcontent, array('id' => 'ts' . $auser->id)); ///Print grade, dropdown or text if ($auser->timemarked > 0) { $teachermodified = '<div id="tt' . $auser->id . '">' . userdate($auser->timemarked) . '</div>'; if ($final_grade->locked or $final_grade->overridden) { $grade = '<div id="g' . $auser->id . '" class="' . $locked_overridden . '">' . $final_grade->formatted_grade . '</div>'; } else { if ($quickgrade) { $attributes = array(); $attributes['tabindex'] = $tabindex++; $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide')); $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes); $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>'; } else { $grade = '<div id="g' . $auser->id . '">' . $this->display_grade($auser->grade) . '</div>'; } } } else { $teachermodified = '<div id="tt' . $auser->id . '"> </div>'; if ($final_grade->locked or $final_grade->overridden) { $grade = '<div id="g' . $auser->id . '" class="' . $locked_overridden . '">' . $final_grade->formatted_grade . '</div>'; } else { if ($quickgrade) { $attributes = array(); $attributes['tabindex'] = $tabindex++; $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide')); $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes); $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>'; } else { $grade = '<div id="g' . $auser->id . '">' . $this->display_grade($auser->grade) . '</div>'; } } } ///Print Comment if ($final_grade->locked or $final_grade->overridden) { $comment = '<div id="com' . $auser->id . '">' . shorten_text(strip_tags($final_grade->str_feedback), 15) . '</div>'; } else { if ($quickgrade) { $comment = '<div id="com' . $auser->id . '">' . '<textarea tabindex="' . $tabindex++ . '" name="submissioncomment[' . $auser->id . ']" id="submissioncomment' . $auser->id . '" rows="2" cols="20">' . $auser->submissioncomment . '</textarea></div>'; } else { $comment = '<div id="com' . $auser->id . '">' . shorten_text(strip_tags($auser->submissioncomment), 15) . '</div>'; } } } else { $studentmodified = '<div id="ts' . $auser->id . '"> </div>'; $teachermodified = '<div id="tt' . $auser->id . '"> </div>'; $status = '<div id="st' . $auser->id . '"> </div>'; if ($final_grade->locked or $final_grade->overridden) { $grade = '<div id="g' . $auser->id . '">' . $final_grade->formatted_grade . '</div>'; $hassubmission = true; } else { if ($quickgrade) { // allow editing $attributes = array(); $attributes['tabindex'] = $tabindex++; $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide')); $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes); $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>'; $hassubmission = true; } else { $grade = '<div id="g' . $auser->id . '">-</div>'; } } if ($final_grade->locked or $final_grade->overridden) { $comment = '<div id="com' . $auser->id . '">' . $final_grade->str_feedback . '</div>'; } else { if ($quickgrade) { $comment = '<div id="com' . $auser->id . '">' . '<textarea tabindex="' . $tabindex++ . '" name="submissioncomment[' . $auser->id . ']" id="submissioncomment' . $auser->id . '" rows="2" cols="20">' . $auser->submissioncomment . '</textarea></div>'; } else { $comment = '<div id="com' . $auser->id . '"> </div>'; } } } if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1 $auser->status = 0; } else { $auser->status = 1; } $buttontext = $auser->status == 1 ? $strupdate : $strgrade; if ($final_grade->locked or $final_grade->overridden) { $buttontext = $strview; } ///No more buttons, we use popups ;-). $popup_url = '/mod/assignment/submissions.php?id=' . $this->cm->id . '&userid=' . $auser->id . '&mode=single' . '&filter=' . $filter . '&offset=' . $offset++; $button = $OUTPUT->action_link($popup_url, $buttontext); $status = '<div id="up' . $auser->id . '" class="s' . $auser->status . '">' . $button . '</div>'; $finalgrade = '<span id="finalgrade_' . $auser->id . '">' . $final_grade->str_grade . '</span>'; $outcomes = ''; if ($uses_outcomes) { foreach ($grading_info->outcomes as $n => $outcome) { $outcomes .= '<div class="outcome"><label for="' . 'outcome_' . $n . '_' . $auser->id . '">' . $outcome->name . '</label>'; $options = make_grades_menu(-$outcome->scaleid); if ($outcome->grades[$auser->id]->locked or !$quickgrade) { $options[0] = get_string('nooutcome', 'grades'); $outcomes .= ': <span id="outcome_' . $n . '_' . $auser->id . '">' . $options[$outcome->grades[$auser->id]->grade] . '</span>'; } else { $attributes = array(); $attributes['tabindex'] = $tabindex++; $attributes['id'] = 'outcome_' . $n . '_' . $auser->id; $outcomes .= ' ' . html_writer::select($options, 'outcome_' . $n . '[' . $auser->id . ']', $outcome->grades[$auser->id]->grade, array(0 => get_string('nooutcome', 'grades')), $attributes); } $outcomes .= '</div>'; } } $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . '</a>'; $extradata = array(); foreach ($extrafields as $field) { $extradata[] = $auser->{$field}; } $row = array_merge(array($picture, $userlink), $extradata, array($grade, $comment, $studentmodified, $teachermodified, $status, $finalgrade)); if ($uses_outcomes) { $row[] = $outcomes; } $table->add_data($row, $rowclass); } $currentposition++; } if ($hassubmission && method_exists($this, 'download_submissions')) { echo html_writer::start_tag('div', array('class' => 'mod-assignment-download-link')); echo html_writer::link(new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id, 'download' => 'zip')), get_string('downloadall', 'assignment')); echo html_writer::end_tag('div'); } $table->print_html(); /// Print the whole table } else { if ($filter == self::FILTER_SUBMITTED) { echo html_writer::tag('div', get_string('nosubmisson', 'assignment'), array('class' => 'nosubmisson')); } else { if ($filter == self::FILTER_REQUIRE_GRADING) { echo html_writer::tag('div', get_string('norequiregrading', 'assignment'), array('class' => 'norequiregrading')); } } } } /// Print quickgrade form around the table if ($quickgrade && $table->started_output && !empty($users)) { $mailinfopref = false; if (get_user_preferences('assignment_mailinfo', 1)) { $mailinfopref = true; } $emailnotification = html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enablenotification', 'assignment')); $emailnotification .= $OUTPUT->help_icon('enablenotification', 'assignment'); echo html_writer::tag('div', $emailnotification, array('class' => 'emailnotification')); $savefeedback = html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'fastg', 'value' => get_string('saveallfeedback', 'assignment'))); echo html_writer::tag('div', $savefeedback, array('class' => 'fastgbutton')); echo html_writer::end_tag('form'); } else { if ($quickgrade) { echo html_writer::end_tag('form'); } } echo '</div>'; /// End of fast grading form /// Mini form for setting user preference $formaction = new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id)); $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class' => 'optionspref')); $mform->addElement('hidden', 'updatepref'); $mform->setDefault('updatepref', 1); $mform->addElement('header', 'qgprefs', get_string('optionalsettings', 'assignment')); $mform->addElement('select', 'filter', get_string('show'), $filters); $mform->setDefault('filter', $filter); $mform->addElement('text', 'perpage', get_string('pagesize', 'assignment'), array('size' => 1)); $mform->setDefault('perpage', $perpage); if ($this->quickgrade_mode_allowed()) { $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade', 'assignment')); $mform->setDefault('quickgrade', $quickgrade); $mform->addHelpButton('quickgrade', 'quickgrade', 'assignment'); } $mform->addElement('submit', 'savepreferences', get_string('savepreferences')); $mform->display(); echo $OUTPUT->footer(); }
/** * Add all the user-related columns to the $columns and $headers arrays. * @param table_sql $table the table being constructed. * @param array $columns the list of columns. Added to. * @param array $headers the columns headings. Added to. */ protected function add_user_columns($table, &$columns, &$headers) { global $CFG; if (!$table->is_downloading() && $CFG->grade_report_showuserimage) { $columns[] = 'picture'; $headers[] = ''; } if (!$table->is_downloading()) { $columns[] = 'fullname'; $headers[] = get_string('name'); } else { $columns[] = 'lastname'; $headers[] = get_string('lastname'); $columns[] = 'firstname'; $headers[] = get_string('firstname'); } // When downloading, some extra fields are always displayed (because // there's no space constraint) so do not include in extra-field list. $extrafields = get_extra_user_fields($this->context, $table->is_downloading() ? array('institution', 'department', 'email') : array()); foreach ($extrafields as $field) { $columns[] = $field; $headers[] = get_user_field_name($field); } if ($table->is_downloading()) { $columns[] = 'institution'; $headers[] = get_string('institution'); $columns[] = 'department'; $headers[] = get_string('department'); $columns[] = 'email'; $headers[] = get_string('email'); } }
/** * This function generates the standard ORDER BY clause for use when generating * lists of users. If you don't have a reason to use a different order, then * you should use this method to generate the order when displaying lists of users. * * If the optional $search parameter is passed, then exact matches to the search * will be sorted first. For example, suppose you have two users 'Al Zebra' and * 'Alan Aardvark'. The default sort is Alan, then Al. If, however, you search for * 'Al', then Al will be listed first. (With two users, this is not a big deal, * but with thousands of users, it is essential.) * * The list of fields scanned for exact matches are: * - firstname * - lastname * - $DB->sql_fullname * - those returned by get_extra_user_fields * * If named parameters are used (which is the default, and highly recommended), * then the parameter names are like :usersortexactN, where N is an int. * * The simplest possible example use is: * list($sort, $params) = users_order_by_sql(); * $sql = 'SELECT * FROM {users} ORDER BY ' . $sort; * * A more complex example, showing that this sort can be combined with other sorts: * list($sort, $sortparams) = users_order_by_sql('u'); * $sql = "SELECT g.id AS groupid, gg.groupingid, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username * FROM {groups} g * LEFT JOIN {groupings_groups} gg ON g.id = gg.groupid * LEFT JOIN {groups_members} gm ON g.id = gm.groupid * LEFT JOIN {user} u ON gm.userid = u.id * WHERE g.courseid = :courseid $groupwhere $groupingwhere * ORDER BY g.name, $sort"; * $params += $sortparams; * * An example showing the use of $search: * list($sort, $sortparams) = users_order_by_sql('u', $search, $this->get_context()); * $order = ' ORDER BY ' . $sort; * $params += $sortparams; * $availableusers = $DB->get_records_sql($fields . $sql . $order, $params, $page*$perpage, $perpage); * * @param string $usertablealias (optional) any table prefix for the {users} table. E.g. 'u'. * @param string $search (optional) a current search string. If given, * any exact matches to this string will be sorted first. * @param context $context the context we are in. Use by get_extra_user_fields. * Defaults to $PAGE->context. * @return array with two elements: * string SQL fragment to use in the ORDER BY clause. For example, "firstname, lastname". * array of parameters used in the SQL fragment. */ function users_order_by_sql($usertablealias = '', $search = null, context $context = null) { global $DB, $PAGE; if ($usertablealias) { $tableprefix = $usertablealias . '.'; } else { $tableprefix = ''; } $sort = "{$tableprefix}lastname, {$tableprefix}firstname, {$tableprefix}id"; $params = array(); if (!$search) { return array($sort, $params); } if (!$context) { $context = $PAGE->context; } $exactconditions = array(); $paramkey = 'usersortexact1'; $exactconditions[] = $DB->sql_fullname($tableprefix . 'firstname', $tableprefix . 'lastname') . ' = :' . $paramkey; $params[$paramkey] = $search; $paramkey++; $fieldstocheck = array_merge(array('firstname', 'lastname'), get_extra_user_fields($context)); foreach ($fieldstocheck as $key => $field) { $exactconditions[] = 'LOWER(' . $tableprefix . $field . ') = LOWER(:' . $paramkey . ')'; $params[$paramkey] = $search; $paramkey++; } $sort = 'CASE WHEN ' . implode(' OR ', $exactconditions) . ' THEN 0 ELSE 1 END, ' . $sort; return array($sort, $params); }
/** * Print the grading page for a single user submission. * * @param moodleform $mform * @return string */ protected function view_single_grade_page($mform) { global $DB, $CFG; $o = ''; $instance = $this->get_instance(); require_once($CFG->dirroot . '/mod/assign/gradeform.php'); // Need submit permission to submit an assignment. require_capability('mod/assign:grade', $this->context); $header = new assign_header($instance, $this->get_context(), false, $this->get_course_module()->id, get_string('grading', 'assign')); $o .= $this->get_renderer()->render($header); // If userid is passed - we are only grading a single student. $rownum = required_param('rownum', PARAM_INT); $useridlistid = optional_param('useridlistid', time(), PARAM_INT); $userid = optional_param('userid', 0, PARAM_INT); $attemptnumber = optional_param('attemptnumber', -1, PARAM_INT); $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist'); if (!$userid) { if (!$useridlist = $cache->get($this->get_course_module()->id . '_' . $useridlistid)) { $useridlist = $this->get_grading_userid_list(); } $cache->set($this->get_course_module()->id . '_' . $useridlistid, $useridlist); } else { $rownum = 0; $useridlist = array($userid); } if ($rownum < 0 || $rownum > count($useridlist)) { throw new coding_exception('Row is out of bounds for the current grading table: ' . $rownum); } $last = false; $userid = $useridlist[$rownum]; if ($rownum == count($useridlist) - 1) { $last = true; } $user = $DB->get_record('user', array('id' => $userid)); if ($user) { $viewfullnames = has_capability('moodle/site:viewfullnames', $this->get_course_context()); $usersummary = new assign_user_summary($user, $this->get_course()->id, $viewfullnames, $this->is_blind_marking(), $this->get_uniqueid_for_user($user->id), get_extra_user_fields($this->get_context())); $o .= $this->get_renderer()->render($usersummary); } $submission = $this->get_user_submission($userid, false, $attemptnumber); $submissiongroup = null; $submissiongroupmemberswhohavenotsubmitted = array(); $teamsubmission = null; $notsubmitted = array(); if ($instance->teamsubmission) { $teamsubmission = $this->get_group_submission($userid, 0, false, $attemptnumber); $submissiongroup = $this->get_submission_group($userid); $groupid = 0; if ($submissiongroup) { $groupid = $submissiongroup->id; } $notsubmitted = $this->get_submission_group_members_who_have_not_submitted($groupid, false); } // Get the requested grade. $grade = $this->get_user_grade($userid, false, $attemptnumber); $flags = $this->get_user_flags($userid, false); if ($this->can_view_submission($userid)) { $gradelocked = ($flags && $flags->locked) || $this->grading_disabled($userid); $extensionduedate = null; if ($flags) { $extensionduedate = $flags->extensionduedate; } $showedit = $this->submissions_open($userid) && ($this->is_any_submission_plugin_enabled()); if ($teamsubmission) { $showsubmit = $showedit && $teamsubmission && ($teamsubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) && !$this->submission_empty($teamsubmission); } else { $showsubmit = $showedit && $submission && ($submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) && !$this->submission_empty($submission); } if (!$this->get_instance()->submissiondrafts) { $showsubmit = false; } $viewfullnames = has_capability('moodle/site:viewfullnames', $this->get_course_context()); $submissionstatus = new assign_submission_status($instance->allowsubmissionsfromdate, $instance->alwaysshowdescription, $submission, $instance->teamsubmission, $teamsubmission, $submissiongroup, $notsubmitted, $this->is_any_submission_plugin_enabled(), $gradelocked, $this->is_graded($userid), $instance->duedate, $instance->cutoffdate, $this->get_submission_plugins(), $this->get_return_action(), $this->get_return_params(), $this->get_course_module()->id, $this->get_course()->id, assign_submission_status::GRADER_VIEW, $showedit, $showsubmit, $viewfullnames, $extensionduedate, $this->get_context(), $this->is_blind_marking(), '', $instance->attemptreopenmethod, $instance->maxattempts); $o .= $this->get_renderer()->render($submissionstatus); } if ($grade) { $data = new stdClass(); if ($grade->grade !== null && $grade->grade >= 0) { $data->grade = format_float($grade->grade, 2); } } else { $data = new stdClass(); $data->grade = ''; } // Warning if required. $allsubmissions = $this->get_all_submissions($userid); if ($attemptnumber != -1) { $params = array('attemptnumber'=>$attemptnumber + 1, 'totalattempts'=>count($allsubmissions)); $message = get_string('editingpreviousfeedbackwarning', 'assign', $params); $o .= $this->get_renderer()->notification($message); } // Now show the grading form. if (!$mform) { $pagination = array('rownum'=>$rownum, 'useridlistid'=>$useridlistid, 'last'=>$last, 'userid'=>optional_param('userid', 0, PARAM_INT), 'attemptnumber'=>$attemptnumber); $formparams = array($this, $data, $pagination); $mform = new mod_assign_grade_form(null, $formparams, 'post', '', array('class'=>'gradeform')); } $o .= $this->get_renderer()->heading(get_string('grade'), 3); $o .= $this->get_renderer()->render(new assign_form('gradingform', $mform)); if (count($allsubmissions) > 1 && $attemptnumber == -1) { $allgrades = $this->get_all_grades($userid); $history = new assign_attempt_history($allsubmissions, $allgrades, $this->get_submission_plugins(), $this->get_feedback_plugins(), $this->get_course_module()->id, $this->get_return_action(), $this->get_return_params(), true, $useridlistid, $rownum); $o .= $this->get_renderer()->render($history); } $msg = get_string('viewgradingformforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user))); $this->add_to_log('view grading form', $msg); $o .= $this->view_footer(); return $o; }
/** * If the current user is to be shown extra user fields when listing or * selecting users, returns a string suitable for including in an SQL select * clause to retrieve those fields. * * @param context $context Context * @param string $alias Alias of user table, e.g. 'u' (default none) * @param string $prefix Prefix for field names using AS, e.g. 'u_' (default none) * @param array $already Array of fields that we're going to include anyway so don't list them (default none) * @return string Partial SQL select clause, beginning with comma, for example ',u.idnumber,u.department' unless it is blank */ function get_extra_user_fields_sql($context, $alias = '', $prefix = '', $already = array()) { $fields = get_extra_user_fields($context, $already); $result = ''; // Add punctuation for alias. if ($alias !== '') { $alias .= '.'; } foreach ($fields as $field) { $result .= ', ' . $alias . $field; if ($prefix) { $result .= ' AS ' . $prefix . $field; } } return $result; }
/** * Builds and returns the rows that will make up the left part of the grader report * This consists of student names and icons, links to user reports and id numbers, as well * as header cells for these columns. It also includes the fillers required for the * categories displayed on the right side of the report. * @param boolean $displayaverages whether to display average rows in the table * @return array Array of html_table_row objects */ public function get_left_rows($displayaverages) { global $CFG, $USER, $OUTPUT; $rows = array(); $showuserimage = $this->get_pref('showuserimage'); $canseeuserreport = has_capability('gradereport/' . $CFG->grade_profilereport . ':view', $this->context); $canseesingleview = has_all_capabilities(array('gradereport/singleview:view', 'moodle/grade:viewall', 'moodle/grade:edit'), $this->context); $hasuserreportcell = $canseeuserreport || $canseesingleview; $strfeedback = $this->get_lang_string("feedback"); $strgrade = $this->get_lang_string('grade'); $extrafields = get_extra_user_fields($this->context); $arrows = $this->get_sort_arrows($extrafields); $colspan = 1 + $hasuserreportcell + count($extrafields); $levels = count($this->gtree->levels) - 1; $fillercell = new html_table_cell(); $fillercell->header = true; $fillercell->attributes['scope'] = 'col'; $fillercell->attributes['class'] = 'cell topleft'; $fillercell->text = html_writer::span(get_string('participants'), 'accesshide'); $fillercell->colspan = $colspan; $fillercell->rowspan = $levels; $row = new html_table_row(array($fillercell)); $rows[] = $row; for ($i = 1; $i < $levels; $i++) { $row = new html_table_row(); $rows[] = $row; } $headerrow = new html_table_row(); $headerrow->attributes['class'] = 'heading'; $studentheader = new html_table_cell(); $studentheader->attributes['class'] = 'header'; $studentheader->scope = 'col'; $studentheader->header = true; $studentheader->id = 'studentheader'; if ($hasuserreportcell) { $studentheader->colspan = 2; } $studentheader->text = $arrows['studentname']; $headerrow->cells[] = $studentheader; foreach ($extrafields as $field) { $fieldheader = new html_table_cell(); $fieldheader->attributes['class'] = 'header userfield user' . $field; $fieldheader->scope = 'col'; $fieldheader->header = true; $fieldheader->text = $arrows[$field]; $headerrow->cells[] = $fieldheader; } $rows[] = $headerrow; $rows = $this->get_left_icons_row($rows, $colspan); $suspendedstring = null; foreach ($this->users as $userid => $user) { $userrow = new html_table_row(); $userrow->id = 'fixed_user_' . $userid; $usercell = new html_table_cell(); $usercell->attributes['class'] = 'header user'; $usercell->header = true; $usercell->scope = 'row'; if ($showuserimage) { $usercell->text = $OUTPUT->user_picture($user, array('visibletoscreenreaders' => false)); } $fullname = fullname($user); $usercell->text .= html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $this->course->id)), $fullname, array('class' => 'username')); if (!empty($user->suspendedenrolment)) { $usercell->attributes['class'] .= ' usersuspended'; //may be lots of suspended users so only get the string once if (empty($suspendedstring)) { $suspendedstring = get_string('userenrolmentsuspended', 'grades'); } $usercell->text .= html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/enrolmentsuspended'), 'title' => $suspendedstring, 'alt' => $suspendedstring, 'class' => 'usersuspendedicon')); } $userrow->cells[] = $usercell; $userreportcell = new html_table_cell(); $userreportcell->attributes['class'] = 'userreport'; $userreportcell->header = false; if ($canseeuserreport) { $a = new stdClass(); $a->user = $fullname; $strgradesforuser = get_string('gradesforuser', 'grades', $a); $url = new moodle_url('/grade/report/' . $CFG->grade_profilereport . '/index.php', array('userid' => $user->id, 'id' => $this->course->id)); $userreportcell->text .= $OUTPUT->action_icon($url, new pix_icon('t/grades', $strgradesforuser)); } if ($canseesingleview) { $url = new moodle_url('/grade/report/singleview/index.php', array('id' => $this->course->id, 'itemid' => $user->id, 'item' => 'user')); $singleview = $OUTPUT->action_icon($url, new pix_icon('t/editstring', get_string('singleview', 'grades', $fullname))); $userreportcell->text .= $singleview; } if ($userreportcell->text) { $userrow->cells[] = $userreportcell; } foreach ($extrafields as $field) { $fieldcell = new html_table_cell(); $fieldcell->attributes['class'] = 'userfield user' . $field; $fieldcell->header = false; $fieldcell->text = $user->{$field}; $userrow->cells[] = $fieldcell; } $userrow->attributes['data-uid'] = $userid; $rows[] = $userrow; } $rows = $this->get_left_range_row($rows, $colspan); if ($displayaverages) { $rows = $this->get_left_avg_row($rows, $colspan, true); $rows = $this->get_left_avg_row($rows, $colspan); } return $rows; }
if ($user = $DB->get_record('user', array('id' => $unlock, 'mnethostid' => $CFG->mnet_localhost_id, 'deleted' => 0))) { login_unlock_account($user); } redirect($returnurl); } } } } } } // create the user filter form $ufiltering = new user_filtering(); echo $OUTPUT->header(); // Carry on with the user listing $context = context_system::instance(); $extracolumns = get_extra_user_fields($context); $columns = array_merge(array('firstname', 'lastname'), $extracolumns, array('city', 'country', 'lastaccess')); foreach ($columns as $column) { $string[$column] = get_user_field_name($column); if ($sort != $column) { $columnicon = ""; if ($column == "lastaccess") { $columndir = "DESC"; } else { $columndir = "ASC"; } } else { $columndir = $dir == "ASC" ? "DESC" : "ASC"; if ($column == "lastaccess") { $columnicon = $dir == "ASC" ? "sort_desc" : "sort_asc"; } else {
/** * displays the full report * @param \stdClass $scorm full SCORM object * @param \stdClass $cm - full course_module object * @param \stdClass $course - full course object * @param string $download - type of download being requested */ public function display($scorm, $cm, $course, $download) { global $CFG, $DB, $OUTPUT, $PAGE; $contextmodule = \context_module::instance($cm->id); $action = optional_param('action', '', PARAM_ALPHA); $attemptids = optional_param_array('attemptid', array(), PARAM_RAW); $attemptsmode = optional_param('attemptsmode', SCORM_REPORT_ATTEMPTS_ALL_STUDENTS, PARAM_INT); $PAGE->set_url(new \moodle_url($PAGE->url, array('attemptsmode' => $attemptsmode))); if ($action == 'delete' && has_capability('mod/scorm:deleteresponses', $contextmodule) && confirm_sesskey()) { if (scorm_delete_responses($attemptids, $scorm)) { // Delete responses. echo $OUTPUT->notification(get_string('scormresponsedeleted', 'scorm'), 'notifysuccess'); } } // Find out current groups mode. $currentgroup = groups_get_activity_group($cm, true); // Detailed report. $mform = new \mod_scorm_report_objectives_settings($PAGE->url, compact('currentgroup')); if ($fromform = $mform->get_data()) { $pagesize = $fromform->pagesize; $showobjectivescore = $fromform->objectivescore; set_user_preference('scorm_report_pagesize', $pagesize); set_user_preference('scorm_report_objectives_score', $showobjectivescore); } else { $pagesize = get_user_preferences('scorm_report_pagesize', 0); $showobjectivescore = get_user_preferences('scorm_report_objectives_score', 0); } if ($pagesize < 1) { $pagesize = SCORM_REPORT_DEFAULT_PAGE_SIZE; } // Select group menu. $displayoptions = array(); $displayoptions['attemptsmode'] = $attemptsmode; $displayoptions['objectivescore'] = $showobjectivescore; $mform->set_data($displayoptions + array('pagesize' => $pagesize)); if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used. if (!$download) { groups_print_activity_menu($cm, new \moodle_url($PAGE->url, $displayoptions)); } } $formattextoptions = array('context' => \context_course::instance($course->id)); // We only want to show the checkbox to delete attempts // if the user has permissions and if the report mode is showing attempts. $candelete = has_capability('mod/scorm:deleteresponses', $contextmodule) && $attemptsmode != SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO; // Select the students. $nostudents = false; if (empty($currentgroup)) { // All users who can attempt scoes. if (!($students = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', 'u.id', '', '', '', '', '', false))) { echo $OUTPUT->notification(get_string('nostudentsyet')); $nostudents = true; $allowedlist = ''; } else { $allowedlist = array_keys($students); } unset($students); } else { // All users who can attempt scoes and who are in the currently selected group. $groupstudents = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', 'u.id', '', '', '', $currentgroup, '', false); if (!$groupstudents) { echo $OUTPUT->notification(get_string('nostudentsingroup')); $nostudents = true; $groupstudents = array(); } $allowedlist = array_keys($groupstudents); unset($groupstudents); } if (!$nostudents) { // Now check if asked download of data. $coursecontext = \context_course::instance($course->id); if ($download) { $filename = clean_filename("{$course->shortname} " . format_string($scorm->name, true, $formattextoptions)); } // Define table columns. $columns = array(); $headers = array(); if (!$download && $candelete) { $columns[] = 'checkbox'; $headers[] = null; } if (!$download && $CFG->grade_report_showuserimage) { $columns[] = 'picture'; $headers[] = ''; } $columns[] = 'fullname'; $headers[] = get_string('name'); $extrafields = get_extra_user_fields($coursecontext); foreach ($extrafields as $field) { $columns[] = $field; $headers[] = get_user_field_name($field); } $columns[] = 'attempt'; $headers[] = get_string('attempt', 'scorm'); $columns[] = 'start'; $headers[] = get_string('started', 'scorm'); $columns[] = 'finish'; $headers[] = get_string('last', 'scorm'); $columns[] = 'score'; $headers[] = get_string('score', 'scorm'); $scoes = $DB->get_records('scorm_scoes', array("scorm" => $scorm->id), 'sortorder, id'); foreach ($scoes as $sco) { if ($sco->launch != '') { $columns[] = 'scograde' . $sco->id; $headers[] = format_string($sco->title, '', $formattextoptions); } } $params = array(); list($usql, $params) = $DB->get_in_or_equal($allowedlist, SQL_PARAMS_NAMED); // Construct the SQL. $select = 'SELECT DISTINCT ' . $DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)') . ' AS uniqueid, '; $select .= 'st.scormid AS scormid, st.attempt AS attempt, ' . \user_picture::fields('u', array('idnumber'), 'userid') . get_extra_user_fields_sql($coursecontext, 'u', '', array('email', 'idnumber')) . ' '; // This part is the same for all cases - join users and scorm_scoes_track tables. $from = 'FROM {user} u '; $from .= 'LEFT JOIN {scorm_scoes_track} st ON st.userid = u.id AND st.scormid = ' . $scorm->id; switch ($attemptsmode) { case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH: // Show only students with attempts. $where = ' WHERE u.id ' . $usql . ' AND st.userid IS NOT NULL'; break; case SCORM_REPORT_ATTEMPTS_STUDENTS_WITH_NO: // Show only students without attempts. $where = ' WHERE u.id ' . $usql . ' AND st.userid IS NULL'; break; case SCORM_REPORT_ATTEMPTS_ALL_STUDENTS: // Show all students with or without attempts. $where = ' WHERE u.id ' . $usql . ' AND (st.userid IS NOT NULL OR st.userid IS NULL)'; break; } $countsql = 'SELECT COUNT(DISTINCT(' . $DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)') . ')) AS nbresults, '; $countsql .= 'COUNT(DISTINCT(' . $DB->sql_concat('u.id', '\'#\'', 'st.attempt') . ')) AS nbattempts, '; $countsql .= 'COUNT(DISTINCT(u.id)) AS nbusers '; $countsql .= $from . $where; $nbmaincolumns = count($columns); // Get number of main columns used. $objectives = get_scorm_objectives($scorm->id); $nosort = array(); foreach ($objectives as $scoid => $sco) { foreach ($sco as $id => $objectivename) { $colid = $scoid . 'objectivestatus' . $id; $columns[] = $colid; $nosort[] = $colid; if (!$displayoptions['objectivescore']) { // Display the objective name only. $headers[] = $objectivename; } else { // Display the objective status header with a "status" suffix to avoid confusion. $headers[] = $objectivename . ' ' . get_string('status', 'scormreport_objectives'); // Now print objective score headers. $colid = $scoid . 'objectivescore' . $id; $columns[] = $colid; $nosort[] = $colid; $headers[] = $objectivename . ' ' . get_string('score', 'scormreport_objectives'); } } } $emptycell = ''; // Used when an empty cell is being printed - in html we add a space. if (!$download) { $emptycell = ' '; $table = new \flexible_table('mod-scorm-report'); $table->define_columns($columns); $table->define_headers($headers); $table->define_baseurl($PAGE->url); $table->sortable(true); $table->collapsible(true); // This is done to prevent redundant data, when a user has multiple attempts. $table->column_suppress('picture'); $table->column_suppress('fullname'); foreach ($extrafields as $field) { $table->column_suppress($field); } foreach ($nosort as $field) { $table->no_sorting($field); } $table->no_sorting('start'); $table->no_sorting('finish'); $table->no_sorting('score'); $table->no_sorting('checkbox'); $table->no_sorting('picture'); foreach ($scoes as $sco) { if ($sco->launch != '') { $table->no_sorting('scograde' . $sco->id); } } $table->column_class('picture', 'picture'); $table->column_class('fullname', 'bold'); $table->column_class('score', 'bold'); $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'attempts'); $table->set_attribute('class', 'generaltable generalbox'); // Start working -- this is necessary as soon as the niceties are over. $table->setup(); } else { if ($download == 'ODS') { require_once "{$CFG->libdir}/odslib.class.php"; $filename .= ".ods"; // Creating a workbook. $workbook = new \MoodleODSWorkbook("-"); // Sending HTTP headers. $workbook->send($filename); // Creating the first worksheet. $sheettitle = get_string('report', 'scorm'); $myxls = $workbook->add_worksheet($sheettitle); // Format types. $format = $workbook->add_format(); $format->set_bold(0); $formatbc = $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb = $workbook->add_format(); $formatb->set_bold(1); $formaty = $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc = $workbook->add_format(); $formatc->set_align('center'); $formatr = $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg = $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); // Here starts workshhet headers. $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else { if ($download == 'Excel') { require_once "{$CFG->libdir}/excellib.class.php"; $filename .= ".xls"; // Creating a workbook. $workbook = new \MoodleExcelWorkbook("-"); // Sending HTTP headers. $workbook->send($filename); // Creating the first worksheet. $sheettitle = get_string('report', 'scorm'); $myxls = $workbook->add_worksheet($sheettitle); // Format types. $format = $workbook->add_format(); $format->set_bold(0); $formatbc = $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb = $workbook->add_format(); $formatb->set_bold(1); $formaty = $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc = $workbook->add_format(); $formatc->set_align('center'); $formatr = $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg = $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else { if ($download == 'CSV') { $csvexport = new \csv_export_writer("tab"); $csvexport->set_filename($filename, ".txt"); $csvexport->add_data($headers); } } } } if (!$download) { $sort = $table->get_sql_sort(); } else { $sort = ''; } // Fix some wired sorting. if (empty($sort)) { $sort = ' ORDER BY uniqueid'; } else { $sort = ' ORDER BY ' . $sort; } if (!$download) { // Add extra limits due to initials bar. list($twhere, $tparams) = $table->get_sql_where(); if ($twhere) { $where .= ' AND ' . $twhere; // Initial bar. $params = array_merge($params, $tparams); } if (!empty($countsql)) { $count = $DB->get_record_sql($countsql, $params); $totalinitials = $count->nbresults; if ($twhere) { $countsql .= ' AND ' . $twhere; } $count = $DB->get_record_sql($countsql, $params); $total = $count->nbresults; } $table->pagesize($pagesize, $total); echo \html_writer::start_div('scormattemptcounts'); if ($count->nbresults == $count->nbattempts) { echo get_string('reportcountattempts', 'scorm', $count); } else { if ($count->nbattempts > 0) { echo get_string('reportcountallattempts', 'scorm', $count); } else { echo $count->nbusers . ' ' . get_string('users'); } } echo \html_writer::end_div(); } // Fetch the attempts. if (!$download) { $attempts = $DB->get_records_sql($select . $from . $where . $sort, $params, $table->get_page_start(), $table->get_page_size()); echo \html_writer::start_div('', array('id' => 'scormtablecontainer')); if ($candelete) { // Start form. $strreallydel = addslashes_js(get_string('deleteattemptcheck', 'scorm')); echo \html_writer::start_tag('form', array('id' => 'attemptsform', 'method' => 'post', 'action' => $PAGE->url->out(false), 'onsubmit' => 'return confirm("' . $strreallydel . '");')); echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'action', 'value' => 'delete')); echo \html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())); echo \html_writer::start_div('', array('style' => 'display: none;')); echo \html_writer::input_hidden_params($PAGE->url); echo \html_writer::end_div(); echo \html_writer::start_div(); } $table->initialbars($totalinitials > 20); // Build table rows. } else { $attempts = $DB->get_records_sql($select . $from . $where . $sort, $params); } if ($attempts) { foreach ($attempts as $scouser) { $row = array(); if (!empty($scouser->attempt)) { $timetracks = scorm_get_sco_runtime($scorm->id, false, $scouser->userid, $scouser->attempt); } else { $timetracks = ''; } if (in_array('checkbox', $columns)) { if ($candelete && !empty($timetracks->start)) { $row[] = \html_writer::checkbox('attemptid[]', $scouser->userid . ':' . $scouser->attempt, false); } else { if ($candelete) { $row[] = ''; } } } if (in_array('picture', $columns)) { $user = new \stdClass(); $additionalfields = explode(',', \user_picture::fields()); $user = username_load_fields_from_object($user, $scouser, null, $additionalfields); $user->id = $scouser->userid; $row[] = $OUTPUT->user_picture($user, array('courseid' => $course->id)); } if (!$download) { $url = new \moodle_url('/user/view.php', array('id' => $scouser->userid, 'course' => $course->id)); $row[] = \html_writer::link($url, fullname($scouser)); } else { $row[] = fullname($scouser); } foreach ($extrafields as $field) { $row[] = s($scouser->{$field}); } if (empty($timetracks->start)) { $row[] = '-'; $row[] = '-'; $row[] = '-'; $row[] = '-'; } else { if (!$download) { $url = new \moodle_url('/mod/scorm/report/userreport.php', array('id' => $cm->id, 'user' => $scouser->userid, 'attempt' => $scouser->attempt)); $row[] = \html_writer::link($url, $scouser->attempt); } else { $row[] = $scouser->attempt; } if ($download == 'ODS' || $download == 'Excel') { $row[] = userdate($timetracks->start, get_string("strftimedatetime", "langconfig")); } else { $row[] = userdate($timetracks->start); } if ($download == 'ODS' || $download == 'Excel') { $row[] = userdate($timetracks->finish, get_string('strftimedatetime', 'langconfig')); } else { $row[] = userdate($timetracks->finish); } $row[] = scorm_grade_user_attempt($scorm, $scouser->userid, $scouser->attempt); } // Print out all scores of attempt. foreach ($scoes as $sco) { if ($sco->launch != '') { if ($trackdata = scorm_get_tracks($sco->id, $scouser->userid, $scouser->attempt)) { if ($trackdata->status == '') { $trackdata->status = 'notattempted'; } $strstatus = get_string($trackdata->status, 'scorm'); if ($trackdata->score_raw != '') { // If raw score exists, print it. $score = $trackdata->score_raw; // Add max score if it exists. if (isset($trackdata->score_max)) { $score .= '/' . $trackdata->score_max; } } else { // ...else print out status. $score = $strstatus; } if (!$download) { $url = new \moodle_url('/mod/scorm/report/userreporttracks.php', array('id' => $cm->id, 'scoid' => $sco->id, 'user' => $scouser->userid, 'attempt' => $scouser->attempt)); $row[] = \html_writer::img($OUTPUT->pix_url($trackdata->status, 'scorm'), $strstatus, array('title' => $strstatus)) . \html_writer::empty_tag('br') . \html_writer::link($url, $score, array('title' => get_string('details', 'scorm'))); } else { $row[] = $score; } // Iterate over tracks and match objective id against values. $scorm2004 = false; if (scorm_version_check($scorm->version, SCORM_13)) { $scorm2004 = true; $objectiveprefix = "cmi.objectives."; } else { $objectiveprefix = "cmi.objectives_"; } $keywords = array(".id", $objectiveprefix); $objectivestatus = array(); $objectivescore = array(); foreach ($trackdata as $name => $value) { if (strpos($name, $objectiveprefix) === 0 && strrpos($name, '.id') !== false) { $num = trim(str_ireplace($keywords, '', $name)); if (is_numeric($num)) { if ($scorm2004) { $element = $objectiveprefix . $num . '.completion_status'; } else { $element = $objectiveprefix . $num . '.status'; } if (isset($trackdata->{$element})) { $objectivestatus[$value] = $trackdata->{$element}; } else { $objectivestatus[$value] = ''; } if ($displayoptions['objectivescore']) { $element = $objectiveprefix . $num . '.score.raw'; if (isset($trackdata->{$element})) { $objectivescore[$value] = $trackdata->{$element}; } else { $objectivescore[$value] = ''; } } } } } // Interaction data. if (!empty($objectives[$trackdata->scoid])) { foreach ($objectives[$trackdata->scoid] as $name) { if (isset($objectivestatus[$name])) { $row[] = s($objectivestatus[$name]); } else { $row[] = $emptycell; } if ($displayoptions['objectivescore']) { if (isset($objectivescore[$name])) { $row[] = s($objectivescore[$name]); } else { $row[] = $emptycell; } } } } // End of interaction data. } else { // If we don't have track data, we haven't attempted yet. $strstatus = get_string('notattempted', 'scorm'); if (!$download) { $row[] = \html_writer::img($OUTPUT->pix_url('notattempted', 'scorm'), $strstatus, array('title' => $strstatus)) . \html_writer::empty_tag('br') . $strstatus; } else { $row[] = $strstatus; } // Complete the empty cells. for ($i = 0; $i < count($columns) - $nbmaincolumns; $i++) { $row[] = $emptycell; } } } } if (!$download) { $table->add_data($row); } else { if ($download == 'Excel' or $download == 'ODS') { $colnum = 0; foreach ($row as $item) { $myxls->write($rownum, $colnum, $item, $format); $colnum++; } $rownum++; } else { if ($download == 'CSV') { $csvexport->add_data($row); } } } } if (!$download) { $table->finish_output(); if ($candelete) { echo \html_writer::start_tag('table', array('id' => 'commands')); echo \html_writer::start_tag('tr') . \html_writer::start_tag('td'); echo \html_writer::link('javascript:select_all_in(\'DIV\', null, \'scormtablecontainer\');', get_string('selectall', 'scorm')) . ' / '; echo \html_writer::link('javascript:deselect_all_in(\'DIV\', null, \'scormtablecontainer\');', get_string('selectnone', 'scorm')); echo ' '; echo \html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('deleteselected', 'scorm'), 'class' => 'btn btn-secondary')); echo \html_writer::end_tag('td') . \html_writer::end_tag('tr') . \html_writer::end_tag('table'); // Close form. echo \html_writer::end_tag('div'); echo \html_writer::end_tag('form'); } echo \html_writer::end_div(); if (!empty($attempts)) { echo \html_writer::start_tag('table', array('class' => 'boxaligncenter')) . \html_writer::start_tag('tr'); echo \html_writer::start_tag('td'); echo $OUTPUT->single_button(new \moodle_url($PAGE->url, array('download' => 'ODS') + $displayoptions), get_string('downloadods'), 'post', ['class' => 'm-t-1']); echo \html_writer::end_tag('td'); echo \html_writer::start_tag('td'); echo $OUTPUT->single_button(new \moodle_url($PAGE->url, array('download' => 'Excel') + $displayoptions), get_string('downloadexcel'), 'post', ['class' => 'm-t-1']); echo \html_writer::end_tag('td'); echo \html_writer::start_tag('td'); echo $OUTPUT->single_button(new \moodle_url($PAGE->url, array('download' => 'CSV') + $displayoptions), get_string('downloadtext'), 'post', ['class' => 'm-t-1']); echo \html_writer::end_tag('td'); echo \html_writer::start_tag('td'); echo \html_writer::end_tag('td'); echo \html_writer::end_tag('tr') . \html_writer::end_tag('table'); } } } else { if ($candelete && !$download) { echo \html_writer::end_div(); echo \html_writer::end_tag('form'); $table->finish_output(); } echo \html_writer::end_div(); } // Show preferences form irrespective of attempts are there to report or not. if (!$download) { $mform->set_data(compact('detailedrep', 'pagesize', 'attemptsmode')); $mform->display(); } if ($download == 'Excel' or $download == 'ODS') { $workbook->close(); exit; } else { if ($download == 'CSV') { $csvexport->download_file(); exit; } } } else { echo $OUTPUT->notification(get_string('noactivity', 'scorm')); } }
public function test_get_extra_user_fields() { global $CFG, $USER, $DB; $this->resetAfterTest(); $this->setAdminUser(); // It would be really nice if there were a way to 'mock' has_capability // checks (either to return true or false) but as there is not, this // test doesn't test the capability check. Presumably, anyone running // unit tests will have the capability. $context = context_system::instance(); // No fields. $CFG->showuseridentity = ''; $this->assertEquals(array(), get_extra_user_fields($context)); // One field. $CFG->showuseridentity = 'frog'; $this->assertEquals(array('frog'), get_extra_user_fields($context)); // Two fields. $CFG->showuseridentity = 'frog,zombie'; $this->assertEquals(array('frog', 'zombie'), get_extra_user_fields($context)); // No fields, except. $CFG->showuseridentity = ''; $this->assertEquals(array(), get_extra_user_fields($context, array('frog'))); // One field. $CFG->showuseridentity = 'frog'; $this->assertEquals(array(), get_extra_user_fields($context, array('frog'))); // Two fields. $CFG->showuseridentity = 'frog,zombie'; $this->assertEquals(array('zombie'), get_extra_user_fields($context, array('frog'))); }
/** * This function generates HTML to display a subscriber overview, primarily used on * the subscribers page if editing was turned off * * @param array $users * @param object $forum * @param object $course * @return string */ public function subscriber_overview($users, $forum, $course) { $output = ''; $modinfo = get_fast_modinfo($course); if (!$users || !is_array($users) || count($users) === 0) { $output .= $this->output->heading(get_string("nosubscribers", "forum")); } else { if (!isset($modinfo->instances['forum'][$forum->id])) { $output .= $this->output->heading(get_string("invalidmodule", "error")); } else { $cm = $modinfo->instances['forum'][$forum->id]; $canviewemail = in_array('email', get_extra_user_fields(context_module::instance($cm->id))); $output .= $this->output->heading(get_string("subscribersto", "forum", "'" . format_string($forum->name) . "'")); $table = new html_table(); $table->cellpadding = 5; $table->cellspacing = 5; $table->tablealign = 'center'; $table->data = array(); foreach ($users as $user) { $info = array($this->output->user_picture($user, array('courseid' => $course->id)), fullname($user)); if ($canviewemail) { array_push($info, $user->email); } $table->data[] = $info; } $output .= html_writer::table($table); } } return $output; }
$PAGE->set_url($url); $PAGE->set_title(get_string('pluginname', 'local_help_desk')); $PAGE->navbar->add(get_string('pluginname', 'local_help_desk')); $PAGE->navbar->add(get_string('accounts', 'local_help_desk')); $PAGE->set_heading($SITE->fullname); $renderer = $PAGE->get_renderer('local_help_desk'); $lib_help_desk = new help_desk(); $hierarchy = new hierarchy(); $ufiltering = new user_filtering_accounts(); //Tab tree (current tab) $tab = 'accounts'; $serialkey_form = new accounts_serialkey_form(NULL, array('skid' => $skid)); echo $OUTPUT->header(); $lib_help_desk->createtabview($tab); //Tab tree $extracolumns = get_extra_user_fields($systemcontext); $ufiltering = new user_filtering_accounts(); $allusernamefields = get_all_user_name_fields(false, null, null, null, true); $columns = array_merge($allusernamefields, $extracolumns, array('city', 'country', 'lastaccess')); foreach ($columns as $column) { $string[$column] = get_user_field_name($column); if ($sort != $column) { $columnicon = ""; if ($column == "lastaccess") { $columndir = "DESC"; } else { $columndir = "ASC"; } } else { $columndir = $dir == "ASC" ? "DESC" : "ASC"; if ($column == "lastaccess") {
/** * Returns a list of issued certificates - sorted for report. * * @param int $certificateid * @param string $sort the sort order * @param bool $groupmode are we in group mode ? * @param stdClass $cm the course module * @param int $page offset * @param int $perpage total per page * @return stdClass the users */ function certificate_get_issues($certificateid, $sort = "ci.timecreated ASC", $groupmode, $cm, $page = 0, $perpage = 0) { global $DB, $USER; $context = context_module::instance($cm->id); $conditionssql = ''; $conditionsparams = array(); // Get all users that can manage this certificate to exclude them from the report. $certmanagers = array_keys(get_users_by_capability($context, 'mod/certificate:manage', 'u.id')); $certmanagers = array_merge($certmanagers, array_keys(get_admins())); list($sql, $params) = $DB->get_in_or_equal($certmanagers, SQL_PARAMS_NAMED, 'cert'); $conditionssql .= "AND NOT u.id {$sql} \n"; $conditionsparams += $params; if ($groupmode) { $canaccessallgroups = has_capability('moodle/site:accessallgroups', $context); $currentgroup = groups_get_activity_group($cm); // If we are viewing all participants and the user does not have access to all groups then return nothing. if (!$currentgroup && !$canaccessallgroups) { return array(); } if ($currentgroup) { if (!$canaccessallgroups) { // Guest users do not belong to any groups. if (isguestuser()) { return array(); } // Check that the user belongs to the group we are viewing. $usersgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid); if ($usersgroups) { if (!isset($usersgroups[$currentgroup])) { return array(); } } else { // They belong to no group, so return an empty array. return array(); } } $groupusers = array_keys(groups_get_members($currentgroup, 'u.*')); if (empty($groupusers)) { return array(); } list($sql, $params) = $DB->get_in_or_equal($groupusers, SQL_PARAMS_NAMED, 'grp'); $conditionssql .= "AND u.id {$sql} "; $conditionsparams += $params; } } $page = (int) $page; $perpage = (int) $perpage; // Get all the users that have certificates issued, should only be one issue per user for a certificate $allparams = $conditionsparams + array('certificateid' => $certificateid); // The picture fields also include the name fields for the user. $picturefields = user_picture::fields('u', get_extra_user_fields($context)); $users = $DB->get_records_sql("SELECT {$picturefields}, u.idnumber, ci.code, ci.timecreated\n FROM {user} u\n INNER JOIN {certificate_issues} ci\n ON u.id = ci.userid\n WHERE u.deleted = 0\n AND ci.certificateid = :certificateid {$conditionssql}\n ORDER BY {$sort}", $allparams, $page * $perpage, $perpage); return $users; }
throw new enrol_ajax_exception('invalidrole'); } if (!has_capability('moodle/role:assign', $manager->get_context()) || !$manager->assign_role_to_user($roleid, $user->id)) { throw new enrol_ajax_exception('assignnotpermitted'); } $outcome->response->roleid = $roleid; break; case 'getassignable': $otheruserroles = optional_param('otherusers', false, PARAM_BOOL); $outcome->response = $manager->get_assignable_roles_for_json($otheruserroles); break; case 'searchotherusers': $search = optional_param('search', '', PARAM_RAW); $page = optional_param('page', 0, PARAM_INT); $outcome->response = $manager->search_other_users($search, $searchanywhere, $page); $extrafields = get_extra_user_fields($context); $useroptions = array(); // User is not enrolled, either link to site profile or do not link at all. if (has_capability('moodle/user:viewdetails', context_system::instance())) { $useroptions['courseid'] = SITEID; } else { $useroptions['link'] = false; } foreach ($outcome->response['users'] as &$user) { $user->userId = $user->id; $user->picture = $OUTPUT->user_picture($user, $useroptions); $user->fullname = fullname($user); $fieldvalues = array(); foreach ($extrafields as $field) { $fieldvalues[] = s($user->{$field}); unset($user->{$field});
'hidden' => $this->urlparams, 'query' => $query, 'searchtype' => $searchtype ); // Generate SQL // Search SQL information $search_info = new stdClass(); $search_info->id = 'id'; $search_info->fullname = 'fullname'; $search_info->sql = null; $search_info->params = null; // Check if user has capability to view emails. $canviewemail = in_array('email', get_extra_user_fields(context_system::instance())); /** * Use whitelist for table to prevent people messing with the query * Required variables from each case statement: * + $search_info->id: Title of id field (defaults to 'id') * + $search_info->fullname: Title of fullname field (defaults to 'fullname') * + $search_info->sql: SQL after "SELECT .." fragment (e,g, 'FROM ... etc'), without the ORDER BY * + $search_info->order: The "ORDER BY" SQL fragment (should contain the ORDER BY text also) * * Remember to generate and include the query SQL in your WHERE clause with: * dialog_get_search_clause() */ switch ($searchtype) { /** * User search