2005-01-25 23:49:36 +00:00
< ? php //$Id$
2005-08-23 19:12:54 +00:00
define ( 'B_QUIZRESULTS_NAME_FORMAT_FULL' , 1 );
define ( 'B_QUIZRESULTS_NAME_FORMAT_ID' , 2 );
define ( 'B_QUIZRESULTS_NAME_FORMAT_ANON' , 3 );
define ( 'B_QUIZRESULTS_GRADE_FORMAT_PCT' , 1 );
define ( 'B_QUIZRESULTS_GRADE_FORMAT_FRA' , 2 );
define ( 'B_QUIZRESULTS_GRADE_FORMAT_ABS' , 3 );
2005-01-25 23:49:36 +00:00
class block_quiz_results extends block_base {
function init () {
$this -> title = get_string ( 'formaltitle' , 'block_quiz_results' );
2005-08-23 19:12:54 +00:00
$this -> version = 2005082300 ;
2005-01-25 23:49:36 +00:00
}
2005-02-01 10:03:21 +00:00
function applicable_formats () {
2005-02-09 15:45:54 +00:00
return array ( 'course' => true , 'mod-quiz' => true );
2005-02-01 10:03:21 +00:00
}
2005-01-25 23:49:36 +00:00
function get_content () {
global $USER , $CFG ;
if ( $this -> content !== NULL ) {
return $this -> content ;
}
$this -> content = new stdClass ;
$this -> content -> text = '' ;
$this -> content -> footer = '' ;
2005-07-19 23:45:02 +00:00
if ( empty ( $this -> instance )) {
return $this -> content ;
}
2005-02-10 17:32:29 +00:00
if ( $this -> instance -> pagetype == 'course-view' ) {
2005-01-25 23:49:36 +00:00
// We need to see if we are monitoring a quiz
$quizid = empty ( $this -> config -> quizid ) ? 0 : $this -> config -> quizid ;
$courseid = $this -> instance -> pageid ;
}
else {
// Assuming we are displayed in the quiz view page
2005-02-01 06:38:42 +00:00
$quizid = $this -> instance -> pageid ;
2005-02-01 06:51:00 +00:00
// A trick to take advantage of instance config and save queries
if ( empty ( $this -> config -> courseid )) {
$modrecord = get_record ( 'modules' , 'name' , 'quiz' );
$cmrecord = get_record ( 'course_modules' , 'module' , $modrecord -> id , 'instance' , $quizid );
$this -> config -> courseid = intval ( $cmrecord -> course );
$this -> instance_config_commit ();
}
$courseid = $this -> config -> courseid ;
2005-01-25 23:49:36 +00:00
}
2006-08-16 08:54:07 +00:00
$context = get_context_instance ( CONTEXT_COURSE , $courseid );
2005-01-25 23:49:36 +00:00
if ( empty ( $quizid )) {
2005-01-26 22:14:22 +00:00
$this -> content -> text = get_string ( 'error_emptyquizid' , 'block_quiz_results' );
2005-01-25 23:49:36 +00:00
return $this -> content ;
}
// Get the quiz record
$quiz = get_record ( 'quiz' , 'id' , $quizid );
if ( empty ( $quiz )) {
2005-01-26 22:14:22 +00:00
$this -> content -> text = get_string ( 'error_emptyquizrecord' , 'block_quiz_results' );
2005-01-25 23:49:36 +00:00
return $this -> content ;
}
// Get the grades for this quiz
2005-01-27 03:53:20 +00:00
$grades = get_records ( 'quiz_grades' , 'quiz' , $quizid , 'grade, timemodified DESC' );
2005-01-25 23:49:36 +00:00
if ( empty ( $grades )) {
// No grades, sorry
2005-01-26 22:14:22 +00:00
// The block will hide itself in this case
2005-01-26 22:22:55 +00:00
return $this -> content ;
2005-01-25 23:49:36 +00:00
}
2005-02-01 07:46:31 +00:00
if ( empty ( $this -> config -> showbest ) && empty ( $this -> config -> showworst )) {
$this -> content -> text = get_string ( 'configuredtoshownothing' , 'block_quiz_results' );
return $this -> content ;
}
2005-01-26 22:14:22 +00:00
$groupmode = NOGROUPS ;
$best = array ();
$worst = array ();
2005-01-25 23:49:36 +00:00
2005-08-23 19:12:54 +00:00
$nameformat = intval ( empty ( $this -> config -> nameformat ) ? B_QUIZRESULTS_NAME_FORMAT_FULL : $this -> config -> nameformat );
// If the block is configured to operate in group mode, or if the name display format
// is other than "fullname", then we need to retrieve the full course record
if ( ! empty ( $this -> config -> usegroups ) || $nameformat != B_QUIZRESULTS_NAME_FORMAT_FULL ) {
$course = get_record_select ( 'course' , 'id = ' . $courseid , 'groupmode, groupmodeforce, student' );
}
2005-01-25 23:49:36 +00:00
if ( ! empty ( $this -> config -> usegroups )) {
2005-01-26 22:14:22 +00:00
// The block was configured to operate in group mode
if ( $course -> groupmodeforce ) {
$groupmode = $course -> groupmode ;
}
else {
$module = get_record_sql ( 'SELECT cm.groupmode FROM ' . $CFG -> prefix . 'modules m LEFT JOIN ' . $CFG -> prefix . 'course_modules cm ON m.id = cm.module WHERE m.name = \'quiz\' AND cm.instance = ' . $quizid );
$groupmode = $module -> groupmode ;
}
// The actual groupmode for the quiz is now known to be $groupmode
2005-01-25 23:49:36 +00:00
}
2005-01-26 22:14:22 +00:00
2006-08-16 08:54:07 +00:00
if ( has_capability ( 'moodle/site:accessallgroups' , $context ) && $groupmode == SEPARATEGROUPS ) {
2005-01-27 17:40:46 +00:00
// We 'll make an exception in this case
$groupmode = VISIBLEGROUPS ;
}
2005-01-26 22:14:22 +00:00
2005-01-27 17:40:46 +00:00
switch ( $groupmode ) {
case VISIBLEGROUPS :
// Display group-mode results
2005-01-26 22:14:22 +00:00
$groups = get_groups ( $courseid );
if ( empty ( $groups )) {
// No groups exist, sorry
$this -> content -> text = get_string ( 'error_nogroupsexist' , 'block_quiz_results' );
return $this -> content ;
}
// Find out all the userids which have a submitted grade
$userids = array ();
foreach ( $grades as $grade ) {
$userids [] = $grade -> userid ;
}
// Now find which groups these users belong in
$groupofuser = get_records_sql (
'SELECT m.userid, m.groupid, g.name FROM ' . $CFG -> prefix . 'groups g LEFT JOIN ' . $CFG -> prefix . 'groups_members m ON g.id = m.groupid ' .
'WHERE g.courseid = ' . $courseid . ' AND m.userid IN (' . implode ( ',' , $userids ) . ')'
);
$groupgrades = array ();
// OK... now, iterate the grades again and sum them up for each group
foreach ( $grades as $grade ) {
if ( isset ( $groupofuser [ $grade -> userid ])) {
// Count this result only if the user is in a group
$groupid = $groupofuser [ $grade -> userid ] -> groupid ;
if ( ! isset ( $groupgrades [ $groupid ])) {
2005-02-18 14:42:04 +00:00
$groupgrades [ $groupid ] = array ( 'sum' => ( float ) $grade -> grade , 'number' => 1 , 'group' => $groupofuser [ $grade -> userid ] -> name );
2005-01-26 22:14:22 +00:00
}
else {
$groupgrades [ $groupid ][ 'sum' ] += $grade -> grade ;
++ $groupgrades [ $groupid ][ 'number' ];
}
}
}
2005-01-27 03:53:20 +00:00
foreach ( $groupgrades as $groupid => $groupgrade ) {
$groupgrades [ $groupid ][ 'average' ] = $groupgrades [ $groupid ][ 'sum' ] / $groupgrades [ $groupid ][ 'number' ];
}
// Sort groupgrades according to average grade, ascending
uasort ( $groupgrades , create_function ( '$a, $b' , 'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);' ));
2005-01-26 22:14:22 +00:00
// How many groups do we have with graded member submissions to show?
$numbest = empty ( $this -> config -> showbest ) ? 0 : min ( $this -> config -> showbest , count ( $groupgrades ));
$numworst = empty ( $this -> config -> showworst ) ? 0 : min ( $this -> config -> showworst , count ( $groupgrades ) - $numbest );
// Collect all the group results we are going to use in $best and $worst
$remaining = $numbest ;
$groupgrade = end ( $groupgrades );
while ( $remaining -- ) {
2005-01-27 03:53:20 +00:00
$best [ key ( $groupgrades )] = $groupgrade [ 'average' ];
2005-01-26 22:14:22 +00:00
$groupgrade = prev ( $groupgrades );
}
$remaining = $numworst ;
$groupgrade = reset ( $groupgrades );
while ( $remaining -- ) {
2005-01-27 03:53:20 +00:00
$worst [ key ( $groupgrades )] = $groupgrade [ 'average' ];
2005-01-26 22:14:22 +00:00
$groupgrade = next ( $groupgrades );
}
// Ready for output!
2005-08-23 19:12:54 +00:00
$gradeformat = intval ( empty ( $this -> config -> gradeformat ) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this -> config -> gradeformat );
2005-01-26 22:14:22 +00:00
2005-02-10 17:32:29 +00:00
if ( $this -> instance -> pagetype != 'mod-quiz-view' ) {
2005-02-01 06:40:50 +00:00
// Don't show header and link to the quiz if we ARE at the quiz...
$this -> content -> text .= '<h1><a href="' . $CFG -> wwwroot . '/mod/quiz/view.php?q=' . $quizid . '">' . $quiz -> name . '</a></h1>' ;
}
2005-01-26 22:14:22 +00:00
$rank = 0 ;
if ( ! empty ( $best )) {
2005-02-01 08:44:04 +00:00
$this -> content -> text .= '<table class="grades"><caption>' ;
$this -> content -> text .= ( $numbest == 1 ? get_string ( 'bestgroupgrade' , 'block_quiz_results' ) : get_string ( 'bestgroupgrades' , 'block_quiz_results' , $numbest ));
$this -> content -> text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>' ;
2005-01-26 22:14:22 +00:00
foreach ( $best as $groupid => $averagegrade ) {
2005-08-23 19:12:54 +00:00
switch ( $nameformat ) {
case B_QUIZRESULTS_NAME_FORMAT_ANON :
case B_QUIZRESULTS_NAME_FORMAT_ID :
$thisname = get_string ( 'group' );
break ;
default :
case B_QUIZRESULTS_NAME_FORMAT_FULL :
$thisname = '<a href="' . $CFG -> wwwroot . '/course/group.php?group=' . $groupid . '&id=' . $courseid . '">' . $groupgrades [ $groupid ][ 'group' ] . '</a>' ;
break ;
}
$this -> content -> text .= '<tr><td>' . ( ++ $rank ) . '.</td><td>' . $thisname . '</td><td>' ;
2005-01-26 22:14:22 +00:00
switch ( $gradeformat ) {
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_FRA :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= ( format_float ( $averagegrade , $quiz -> decimalpoints ) . '/' . $quiz -> grade );
2005-01-26 22:14:22 +00:00
break ;
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_ABS :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= format_float ( $averagegrade , $quiz -> decimalpoints );
2005-01-26 22:14:22 +00:00
break ;
default :
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_PCT :
2005-02-18 14:42:04 +00:00
$this -> content -> text .= round (( float ) $averagegrade / ( float ) $quiz -> grade * 100 ) . '%' ;
2005-01-26 22:14:22 +00:00
break ;
}
$this -> content -> text .= '</td></tr>' ;
}
$this -> content -> text .= '</tbody></table>' ;
}
$rank = 0 ;
if ( ! empty ( $worst )) {
$worst = array_reverse ( $worst , true );
2005-02-01 08:44:04 +00:00
$this -> content -> text .= '<table class="grades"><caption>' ;
$this -> content -> text .= ( $numworst == 1 ? get_string ( 'worstgroupgrade' , 'block_quiz_results' ) : get_string ( 'worstgroupgrades' , 'block_quiz_results' , $numworst ));
$this -> content -> text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>' ;
2005-01-26 22:14:22 +00:00
foreach ( $worst as $groupid => $averagegrade ) {
2005-08-23 19:12:54 +00:00
switch ( $nameformat ) {
case B_QUIZRESULTS_NAME_FORMAT_ANON :
case B_QUIZRESULTS_NAME_FORMAT_ID :
$thisname = get_string ( 'group' );
break ;
default :
case B_QUIZRESULTS_NAME_FORMAT_FULL :
$thisname = '<a href="' . $CFG -> wwwroot . '/course/group.php?group=' . $groupid . '&id=' . $courseid . '">' . $groupgrades [ $groupid ][ 'group' ] . '</a>' ;
break ;
}
$this -> content -> text .= '<tr><td>' . ( ++ $rank ) . '.</td><td>' . $thisname . '</td><td>' ;
2005-01-26 22:14:22 +00:00
switch ( $gradeformat ) {
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_FRA :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= ( format_float ( $averagegrade , $quiz -> decimalpoints ) . '/' . $quiz -> grade );
2005-01-26 22:14:22 +00:00
break ;
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_ABS :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= format_float ( $averagegrade , $quiz -> decimalpoints );
2005-01-26 22:14:22 +00:00
break ;
default :
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_PCT :
2005-02-18 14:42:04 +00:00
$this -> content -> text .= round (( float ) $averagegrade / ( float ) $quiz -> grade * 100 ) . '%' ;
2005-01-26 22:14:22 +00:00
break ;
}
$this -> content -> text .= '</td></tr>' ;
}
$this -> content -> text .= '</tbody></table>' ;
}
2005-01-27 17:40:46 +00:00
break ;
2005-01-26 22:14:22 +00:00
2005-01-27 17:40:46 +00:00
case SEPARATEGROUPS :
// This is going to be just like no-groups mode, only we 'll filter
// out the grades from people not in our group.
if ( empty ( $USER ) || empty ( $USER -> id )) {
// Not logged in, so show nothing
return $this -> content ;
}
$mygroups = get_groups ( $courseid , $USER -> id );
if ( empty ( $mygroups )) {
// Not member of a group, show nothing
return $this -> content ;
}
$mygroupsusers = get_records_list ( 'groups_members' , 'groupid' , implode ( ',' , array_keys ( $mygroups )), '' , 'userid, id' );
// There should be at least one user there, ourselves. So no more tests.
// Just filter out the grades belonging to other users, and proceed as if there were no groups
$strallowedusers = implode ( ',' , array_keys ( $mygroupsusers ));
$grades = array_filter ( $grades , create_function ( '$el' , '$allowed = explode(",", "' . $strallowedusers . '"); return in_array($el->userid, $allowed);' ));
// NO break; HERE, JUST GO AHEAD
default :
case NOGROUPS :
2005-01-25 23:49:36 +00:00
// Single user mode
2005-01-26 22:14:22 +00:00
$numbest = empty ( $this -> config -> showbest ) ? 0 : min ( $this -> config -> showbest , count ( $grades ));
$numworst = empty ( $this -> config -> showworst ) ? 0 : min ( $this -> config -> showworst , count ( $grades ) - $numbest );
2005-01-25 23:49:36 +00:00
// Collect all the usernames we are going to need
$remaining = $numbest ;
$grade = end ( $grades );
while ( $remaining -- ) {
$best [ $grade -> userid ] = $grade -> id ;
$grade = prev ( $grades );
}
$remaining = $numworst ;
$grade = reset ( $grades );
while ( $remaining -- ) {
$worst [ $grade -> userid ] = $grade -> id ;
$grade = next ( $grades );
}
if ( empty ( $best ) && empty ( $worst )) {
// Nothing to show, for some reason...
return $this -> content ;
}
// Now grab all the users from the database
$userids = array_merge ( array_keys ( $best ), array_keys ( $worst ));
2005-08-23 19:12:54 +00:00
$users = get_records_list ( 'user' , 'id' , implode ( ',' , $userids ), '' , 'id, firstname, lastname, idnumber' );
2005-01-25 23:49:36 +00:00
// Ready for output!
2005-08-23 19:12:54 +00:00
$gradeformat = intval ( empty ( $this -> config -> gradeformat ) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this -> config -> gradeformat );
2005-01-25 23:49:36 +00:00
2005-02-10 17:32:29 +00:00
if ( $this -> instance -> pagetype != 'mod-quiz-view' ) {
2005-02-01 06:40:50 +00:00
// Don't show header and link to the quiz if we ARE at the quiz...
$this -> content -> text .= '<h1><a href="' . $CFG -> wwwroot . '/mod/quiz/view.php?q=' . $quizid . '">' . $quiz -> name . '</a></h1>' ;
}
2005-01-25 23:49:36 +00:00
$rank = 0 ;
if ( ! empty ( $best )) {
2005-02-01 08:44:04 +00:00
$this -> content -> text .= '<table class="grades"><caption>' ;
$this -> content -> text .= ( $numbest == 1 ? get_string ( 'bestgrade' , 'block_quiz_results' ) : get_string ( 'bestgrades' , 'block_quiz_results' , $numbest ));
$this -> content -> text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>' ;
2005-01-25 23:49:36 +00:00
foreach ( $best as $userid => $gradeid ) {
2005-08-23 19:12:54 +00:00
switch ( $nameformat ) {
case B_QUIZRESULTS_NAME_FORMAT_ID :
$thisname = $course -> student . ' ' . intval ( $users [ $userid ] -> idnumber );
break ;
case B_QUIZRESULTS_NAME_FORMAT_ANON :
$thisname = $course -> student ;
break ;
default :
case B_QUIZRESULTS_NAME_FORMAT_FULL :
$thisname = '<a href="' . $CFG -> wwwroot . '/user/view.php?id=' . $userid . '&course=' . $courseid . '">' . fullname ( $users [ $userid ]) . '</a>' ;
break ;
}
$this -> content -> text .= '<tr><td>' . ( ++ $rank ) . '.</td><td>' . $thisname . '</td><td>' ;
2005-01-25 23:49:36 +00:00
switch ( $gradeformat ) {
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_FRA :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= ( format_float ( $grades [ $gradeid ] -> grade , $quiz -> decimalpoints ) . '/' . $quiz -> grade );
2005-01-25 23:49:36 +00:00
break ;
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_ABS :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= format_float ( $grades [ $gradeid ] -> grade , $quiz -> decimalpoints );
2005-01-25 23:49:36 +00:00
break ;
default :
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_PCT :
2005-04-27 13:54:44 +00:00
if ( $quiz -> grade ) {
$this -> content -> text .= round (( float ) $grades [ $gradeid ] -> grade / ( float ) $quiz -> grade * 100 ) . '%' ;
} else {
$this -> content -> text .= '--%' ;
}
2005-01-25 23:49:36 +00:00
break ;
}
$this -> content -> text .= '</td></tr>' ;
}
$this -> content -> text .= '</tbody></table>' ;
}
$rank = 0 ;
if ( ! empty ( $worst )) {
$worst = array_reverse ( $worst , true );
2005-02-01 08:44:04 +00:00
$this -> content -> text .= '<table class="grades"><caption>' ;
$this -> content -> text .= ( $numworst == 1 ? get_string ( 'worstgrade' , 'block_quiz_results' ) : get_string ( 'worstgrades' , 'block_quiz_results' , $numworst ));
$this -> content -> text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>' ;
2005-01-25 23:49:36 +00:00
foreach ( $worst as $userid => $gradeid ) {
2005-08-23 19:12:54 +00:00
switch ( $nameformat ) {
case B_QUIZRESULTS_NAME_FORMAT_ID :
$thisname = $course -> student . ' ' . intval ( $users [ $userid ] -> idnumber );
break ;
case B_QUIZRESULTS_NAME_FORMAT_ANON :
$thisname = $course -> student ;
break ;
default :
case B_QUIZRESULTS_NAME_FORMAT_FULL :
$thisname = '<a href="' . $CFG -> wwwroot . '/user/view.php?id=' . $userid . '&course=' . $courseid . '">' . fullname ( $users [ $userid ]) . '</a>' ;
break ;
}
$this -> content -> text .= '<tr><td>' . ( ++ $rank ) . '.</td><td>' . $thisname . '</td><td>' ;
2005-01-25 23:49:36 +00:00
switch ( $gradeformat ) {
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_FRA :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= ( format_float ( $grades [ $gradeid ] -> grade , $quiz -> decimalpoints ) . '/' . $quiz -> grade );
2005-01-25 23:49:36 +00:00
break ;
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_ABS :
2005-02-14 20:26:11 +00:00
$this -> content -> text .= format_float ( $grades [ $gradeid ] -> grade , $quiz -> decimalpoints );
2005-01-25 23:49:36 +00:00
break ;
default :
2005-08-23 19:12:54 +00:00
case B_QUIZRESULTS_GRADE_FORMAT_PCT :
2005-02-18 14:42:04 +00:00
$this -> content -> text .= round (( float ) $grades [ $gradeid ] -> grade / ( float ) $quiz -> grade * 100 ) . '%' ;
2005-01-25 23:49:36 +00:00
break ;
}
$this -> content -> text .= '</td></tr>' ;
}
$this -> content -> text .= '</tbody></table>' ;
}
2005-01-27 17:40:46 +00:00
break ;
2005-01-25 23:49:36 +00:00
}
return $this -> content ;
}
2005-02-01 10:03:21 +00:00
function instance_allow_multiple () {
2005-01-25 23:49:36 +00:00
return true ;
}
}
?>