Browse Source

Concentrate grades update method in one place

MOODLE_31_STABLE
Antonio Carlos Mariani 9 years ago
parent
commit
0129310e21
  1. 22
      classes/structure.php
  2. 249
      classes/summary.php
  3. 114
      locallib.php
  4. 4
      preferences.php
  5. 8
      sessions.php

22
classes/structure.php

@ -857,27 +857,7 @@ class mod_attendance_structure {
}
public function update_users_grade($userids) {
global $DB;
$grades = array();
if ($this->grade < 0) {
$dbparams = array('id' => -($this->grade));
$this->scale = $DB->get_record('scale', $dbparams);
$scalearray = explode(',', $this->scale->scale);
$attendancegrade = count($scalearray);
} else {
$attendancegrade = $this->grade;
}
foreach ($userids as $userid) {
$grades[$userid] = new stdClass();
$grades[$userid]->userid = $userid;
$grades[$userid]->rawgrade = attendance_calc_user_grade_fraction($this->get_user_grade($userid),
$this->get_user_max_grade($userid)) * $attendancegrade;
}
return grade_update('mod/attendance', $this->course->id, 'mod', 'attendance',
$this->id, 0, $grades);
attendance_update_users_grade($this, $userids);
}
public function get_user_filtered_sessions_log($userid) {

249
classes/summary.php

@ -0,0 +1,249 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class that computes summary of users points
*
* @package mod_attendance
* @copyright 2016 Antonio Carlos Mariani http://antonio.c.mariani@gmail.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_attendance_summary {
/** @var int attendance instance identifier */
private $attendanceid;
/** @var stdclass course course data*/
private $course;
/** @var int groupmode*/
private $groupmode;
/** @var array userspoints (userid, numtakensessions, points, maxpoints) */
private $userspoints;
/** @var array pointsbygroup (groupid, numsessions, maxpoints) */
private $maxpointsbygroupsessions;
/**
* Initializes the class
*
* @param int attendance instance identifier
* @param array userids user instances identifier
* @param int $startdate Attendance sessions startdate
* @param int $enddate Attendance sessions enddate
*/
public function __construct($attendanceid, $userids=array(), $startdate = '', $enddate = '') {
$this->attendanceid = $attendanceid;
$this->compute_users_points($userids, $startdate, $enddate);
}
/**
* Returns true if the user has some session with points
*
* @param int userid User instance id
*
* @return boolean
*/
public function has_taken_sessions($userid) {
return isset($this->userspoints[$userid]);
}
/**
* Returns true if the corresponding attendance instance is currently configure to work with grades (points)
*
* @return boolean
*/
public function with_groups() {
return $this->groupmode > 0;
}
/**
* Returns the groupmode of the corresponding attendance instance
*
* @return int
*/
public function get_groupmode() {
return $this->groupmode;
}
/**
* Returns a summary of the points assigned to the user related to the taken sessions
*
* @param int userid User instance id
*
* @return array
*/
public function get_taken_sessions_summary_for($userid) {
$usersummary = new stdClass();
if ($this->has_taken_sessions($userid)) {
$usersummary->numtakensessions = $this->userspoints[$userid]->numtakensessions;
$usersummary->takensessionspoints = $this->userspoints[$userid]->points;
$usersummary->takensessionsmaxpoints = $this->userspoints[$userid]->maxpoints;
} else {
$usersummary->numtakensessions = 0;
$usersummary->takensessionspoints = 0;
$usersummary->takensessionsmaxpoints = 0;
}
$usersummary->takensessionspercentage = attendance_calc_fraction($usersummary->takensessionspoints, $usersummary->takensessionsmaxpoints);
return $usersummary;
}
/**
* Returns a summary of the points assigned to the user, both related to taken sessions and related to all sessions
*
* @param int userid User instance id
*
* @return array
*/
public function get_all_sessions_summary_for($userid) {
$usersummary = $this->get_taken_sessions_summary_for($userid);
if (!isset($this->maxpointsbygroupsessions)) {
$this->compute_maxpoints_by_group_session();
}
$usersummary->numallsessions = $this->maxpointsbygroupsessions[0]->numsessions;
$usersummary->allsessionsmaxpoints = $this->maxpointsbygroupsessions[0]->maxpoints;
if ($this->with_groups()) {
$groupids = array_keys(groups_get_all_groups($this->course->id, $userid));
foreach ($groupids as $gid) {
if (isset($this->maxpointsbygroupsessions[$gid])) {
$usersummary->numallsessions += $this->maxpointsbygroupsessions[$gid]->numsessions;
$usersummary->allsessionsmaxpoints += $this->maxpointsbygroupsessions[$gid]->maxpoints;
}
}
}
$usersummary->allsessionspercentage = attendance_calc_fraction($usersummary->takensessionspoints, $usersummary->allsessionsmaxpoints);
$deltapoints = $usersummary->allsessionsmaxpoints - $usersummary->takensessionsmaxpoints;
$usersummary->maxpossiblepoints = $usersummary->takensessionspoints + $deltapoints;
$usersummary->maxpossiblepercentage = attendance_calc_fraction($usersummary->maxpossiblepoints, $usersummary->allsessionsmaxpoints);
return $usersummary;
}
/**
* Computes the summary of points for the users that have some taken session
*
* @param array userids user instances identifier
* @param int $startdate Attendance sessions startdate
* @param int $enddate Attendance sessions enddate
* @return (userid, numtakensessions, points, maxpoints)
*/
private function compute_users_points($userids=array(), $startdate = '', $enddate = '') {
global $DB;
list($this->course, $cm) = get_course_and_cm_from_instance($this->attendanceid, 'attendance');
$this->groupmode = $cm->effectivegroupmode;
$params = array(
'attid' => $this->attendanceid,
'attid2' => $this->attendanceid,
'cstartdate' => $this->course->startdate,
);
$where = '';
if (!empty($userids)) {
list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$where .= ' AND atl.studentid ' . $insql;
$params = array_merge($params, $inparams);
}
if (!empty($startdate)) {
$where .= ' AND ats.sessdate >= :startdate';
$params['startdate'] = $startdate;
}
if (!empty($enddate)) {
$where .= ' AND ats.sessdate < :enddate ';
$params['enddate'] = $enddate;
}
$joingroup = '';
if ($this->with_groups()) {
$joingroup = 'LEFT JOIN {groups_members} gm ON (gm.userid = atl.studentid AND gm.groupid = ats.groupid)';
$where .= ' AND (ats.groupid = 0 or gm.id is NOT NULL)';
} else {
$where .= ' AND ats.groupid = 0';
}
$sql = "SELECT userid, COUNT(*) AS numtakensessions, SUM(grade) AS points, SUM(maxgrade) AS maxpoints
FROM (SELECT atl.studentid AS userid, ats.id AS sessionid, stg.grade, stm.maxgrade
FROM {attendance_sessions} ats
JOIN {attendance_log} atl ON (atl.sessionid = ats.id)
JOIN {attendance_statuses} stg ON (stg.id = atl.statusid AND stg.deleted = 0 AND stg.visible = 1)
JOIN (SELECT setnumber, MAX(grade) AS maxgrade
FROM {attendance_statuses}
WHERE attendanceid = :attid2
AND deleted = 0
AND visible = 1
GROUP BY setnumber) stm
ON (stm.setnumber = ats.statusset)
{$joingroup}
WHERE ats.attendanceid = :attid
AND ats.sessdate >= :cstartdate
AND ats.lasttakenby != 0
{$where}
) sess
GROUP BY userid";
$this->userspoints = $DB->get_records_sql($sql, $params);
}
/**
* Computes and store the maximum points possible for each group session
*
* @return null
*/
private function compute_maxpoints_by_group_session() {
global $DB;
$params = array(
'attid' => $this->attendanceid,
'attid2' => $this->attendanceid,
'cstartdate' => $this->course->startdate,
);
$where = '';
if (!$this->with_groups()) {
$where = 'AND sess.groupid = 0';
}
$sql = "SELECT sess.groupid, COUNT(*) AS numsessions, SUM(stamax.maxgrade) AS maxpoints
FROM {attendance_sessions} sess
JOIN (SELECT setnumber, MAX(grade) AS maxgrade
FROM {attendance_statuses}
WHERE attendanceid = :attid2
AND deleted = 0
AND visible = 1
GROUP BY setnumber) stamax
ON (stamax.setnumber = sess.statusset)
WHERE sess.attendanceid = :attid
AND sess.sessdate >= :cstartdate
{$where}
GROUP BY sess.groupid";
$this->maxpointsbygroupsessions = $DB->get_records_sql($sql, $params);
if (!isset($this->maxpointsbygroupsessions[0])) {
$gpoints = new stdClass();
$gpoints->numsessions = 0;
$gpoints->maxpoints = 0;
$this->maxpointsbygroupsessions[0] = $gpoints;
}
}
}

114
locallib.php

@ -189,73 +189,20 @@ function attendance_get_user_courses_attendances($userid) {
}
/**
* Used to caclulate usergrade based on rawgrade and max grade.
* Used to calculate a fraction based on the part and total values
*
* @param float $grade - raw grade for user
* @param float $maxgrade - maxgrade for this session.
* @return float the calculated grade.
* @param float $part - part of the total value
* @param float $total - total value.
* @return float the calculated fraction.
*/
function attendance_calc_user_grade_fraction($grade, $maxgrade) {
if ($maxgrade == 0) {
function attendance_calc_fraction($part, $total) {
if ($total == 0) {
return 0;
} else {
return $grade / $maxgrade;
return $part / $total;
}
}
/**
* Update all user grades - used when settings have changed.
*
* @param mod_attendance_structure $attendance - Full attendance class.
* @param stdclass $coursemodule - full coursemodule record
* @return float the calculated grade.
*/
function attendance_update_all_users_grades(mod_attendance_structure $attendance, $coursemodule) {
global $DB;
$grades = array();
$course = $attendance->course;
$userids = array_keys(get_enrolled_users($attendance->context, 'mod/attendance:canbelisted', 0, 'u.id'));
$attgrades = grade_get_grades($course->id, 'mod', 'attendance', $attendance->id, $userids);
$usergrades = [];
if (!empty($attgrades->items[0]) and !empty($attgrades->items[0]->grades)) {
$usergrades = $attgrades->items[0]->grades;
}
$statuses = attendance_get_statuses($attendance->id);
if ($attendance->grade < 0) {
$dbparams = array('id' => -($attendance->grade));
$scale = $DB->get_record('scale', $dbparams);
$scalearray = explode(',', $scale->scale);
$gradebookmaxgrade = count($scalearray);
} else {
$gradebookmaxgrade = $attendance->grade;
}
foreach ($usergrades as $userid => $existinggrade) {
if (is_null($existinggrade->grade)) {
// Don't update grades where one doesn't exist yet.
continue;
}
$grade = new stdClass;
$grade->userid = $userid;
$userstatusesstat = attendance_get_user_statuses_stat($attendance->id, $course->startdate, $userid, $coursemodule);
$usertakensesscount = attendance_get_user_taken_sessions_count($attendance->id, $course->startdate, $userid, $coursemodule);
$usergrade = attendance_get_user_grade($userstatusesstat, $statuses);
$usermaxgrade = attendance_get_user_max_grade($usertakensesscount, $statuses);
$grade->rawgrade = attendance_calc_user_grade_fraction($usergrade, $usermaxgrade) * $gradebookmaxgrade;
$grades[$userid] = $grade;
}
if (!empty($grades)) {
$result = grade_update('mod/attendance', $course->id, 'mod', 'attendance',
$attendance->id, 0, $grades);
} else {
$result = true;
}
return $result;
}
/**
* Check to see if statusid in use to help prevent deletion etc.
*
@ -308,3 +255,50 @@ function attendance_get_max_statusset($attendanceid) {
}
return 0;
}
/**
* Update user grades
*
* @param mixed mod_attendance_structure|stdClass $attendance
* @param array $userids
*/
function attendance_update_users_grade($attendance, $userids=array()) {
global $DB;
if (empty($attendance->grade)) {
return false;
}
list($course, $cm) = get_course_and_cm_from_instance($attendance->id, 'attendance');
$summary = new mod_attendance_summary($attendance->id, $userids);
if (empty($userids)) {
$context = context_module::instance($cm->id);
$userids = array_keys(get_enrolled_users($context, 'mod/attendance:canbelisted', 0, 'u.id'));
}
if ($attendance->grade < 0) {
$dbparams = array('id' => -($attendance->grade));
$scale = $DB->get_record('scale', $dbparams);
$scalearray = explode(',', $scale->scale);
$attendancegrade = count($scalearray);
} else {
$attendancegrade = $attendance->grade;
}
$grades = array();
foreach ($userids as $userid) {
$grades[$userid] = new stdClass();
$grades[$userid]->userid = $userid;
if ($summary->has_taken_sessions($userid)) {
$usersummary = $summary->get_taken_sessions_summary_for($userid);
$grades[$userid]->rawgrade = $usersummary->takensessionspercentage * $attendancegrade;
} else {
$grades[$userid]->rawgrade = null;
}
}
return grade_update('mod/attendance', $course->id, 'mod', 'attendance', $attendance->id, 0, $grades);
}

4
preferences.php

@ -122,9 +122,7 @@ switch ($att->pageparams->action) {
$status = $statuses[$id];
$errors[$id] = $att->update_status($status, $acronym[$id], $description[$id], $grade[$id], null);
}
if ($att->grade > 0) {
attendance_update_all_users_grades($att, $cm);
}
attendance_update_users_grade($att);
break;
}

8
sessions.php

@ -113,9 +113,7 @@ switch ($att->pageparams->action) {
if (isset($confirm) && confirm_sesskey()) {
$att->delete_sessions(array($sessionid));
if ($att->grade > 0) {
attendance_update_all_users_grades($att, $cm);
}
attendance_update_users_grade($att);
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
@ -142,9 +140,7 @@ switch ($att->pageparams->action) {
$sessionsids = explode('_', $sessionsids);
$att->delete_sessions($sessionsids);
if ($att->grade > 0) {
attendance_update_all_users_grades($att, $cm);
}
attendance_update_users_grade($att);
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
$sessid = optional_param_array('sessid', '', PARAM_SEQUENCE);

Loading…
Cancel
Save