Antonio Carlos Mariani
9 years ago
5 changed files with 307 additions and 90 deletions
@ -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; |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue