Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/blocks/quiz_results/block_quiz_results.php
Go to the documentation of this file.
00001 <?php
00002 // This file is part of Moodle - http://moodle.org/
00003 //
00004 // Moodle is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // Moodle is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00016 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00029 require_once($CFG->dirroot . '/mod/quiz/lib.php');
00030 
00031 
00043 define('B_QUIZRESULTS_NAME_FORMAT_FULL', 1);
00044 define('B_QUIZRESULTS_NAME_FORMAT_ID',   2);
00045 define('B_QUIZRESULTS_NAME_FORMAT_ANON', 3);
00046 define('B_QUIZRESULTS_GRADE_FORMAT_PCT', 1);
00047 define('B_QUIZRESULTS_GRADE_FORMAT_FRA', 2);
00048 define('B_QUIZRESULTS_GRADE_FORMAT_ABS', 3);
00049 
00050 class block_quiz_results extends block_base {
00051     function init() {
00052         $this->title = get_string('pluginname', 'block_quiz_results');
00053     }
00054 
00055     function applicable_formats() {
00056         return array('course' => true, 'mod-quiz' => true);
00057     }
00058 
00064     public function get_owning_quiz() {
00065         if (empty($this->instance->parentcontextid)) {
00066             return 0;
00067         }
00068         $parentcontext = get_context_instance_by_id($this->instance->parentcontextid);
00069         if ($parentcontext->contextlevel != CONTEXT_MODULE) {
00070             return 0;
00071         }
00072         $cm = get_coursemodule_from_id('quiz', $parentcontext->instanceid);
00073         if (!$cm) {
00074             return 0;
00075         }
00076         return $cm->instance;
00077     }
00078 
00079     function instance_config_save($data) {
00080         if (empty($data->quizid)) {
00081             $data->quizid = $this->get_owning_quiz();
00082         }
00083         parent::instance_config_save($data);
00084     }
00085 
00086     function get_content() {
00087         global $USER, $CFG, $DB;
00088 
00089         if ($this->content !== NULL) {
00090             return $this->content;
00091         }
00092 
00093         $this->content = new stdClass;
00094         $this->content->text = '';
00095         $this->content->footer = '';
00096 
00097         if (empty($this->instance)) {
00098             return $this->content;
00099         }
00100 
00101         if ($this->page->activityname == 'quiz' && $this->page->context->id == $this->instance->parentcontextid) {
00102             $quiz = $this->page->activityrecord;
00103             $quizid = $quiz->id;
00104             $courseid = $this->page->course->id;
00105             $inquiz = true;
00106         } else if (!empty($this->config->quizid)) {
00107             $quizid = $this->config->quizid;
00108             $quiz = $DB->get_record('quiz', array('id' => $quizid));
00109             if (empty($quiz)) {
00110                 $this->content->text = get_string('error_emptyquizrecord', 'block_quiz_results');
00111                 return $this->content;
00112             }
00113             $courseid = $quiz->course;
00114             $inquiz = false;
00115         } else {
00116             $quizid = 0;
00117         }
00118 
00119         if (empty($quizid)) {
00120             $this->content->text = get_string('error_emptyquizid', 'block_quiz_results');
00121             return $this->content;
00122         }
00123 
00124         if (empty($this->config->showbest) && empty($this->config->showworst)) {
00125             $this->content->text = get_string('configuredtoshownothing', 'block_quiz_results');
00126             return $this->content;
00127         }
00128 
00129         // Get the grades for this quiz
00130         $grades = $DB->get_records('quiz_grades', array('quiz' => $quizid), 'grade, timemodified DESC');
00131 
00132         if (empty($grades)) {
00133             // No grades, sorry
00134             // The block will hide itself in this case
00135             return $this->content;
00136         }
00137 
00138         $groupmode = NOGROUPS;
00139         $best      = array();
00140         $worst     = array();
00141 
00142         if (!empty($this->config->nameformat)) {
00143             $nameformat = $this->config->nameformat;
00144         } else {
00145             $nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL;
00146         }
00147 
00148         if (!empty($this->config->usegroups)) {
00149             if ($inquiz) {
00150                 $cm = $this->page->cm;
00151                 $context = $this->page->context;
00152             } else {
00153                 $cm = get_coursemodule_from_instance('quiz', $quizid, $courseid);
00154                 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
00155             }
00156             $groupmode = groups_get_activity_groupmode($cm);
00157 
00158             if ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context)) {
00159                 // We 'll make an exception in this case
00160                 $groupmode = VISIBLEGROUPS;
00161             }
00162         }
00163 
00164         switch ($groupmode) {
00165             case VISIBLEGROUPS:
00166             // Display group-mode results
00167             $groups = groups_get_all_groups($courseid);
00168 
00169             if(empty($groups)) {
00170                 // No groups exist, sorry
00171                 $this->content->text = get_string('error_nogroupsexist', 'block_quiz_results');
00172                 return $this->content;
00173             }
00174 
00175             // Find out all the userids which have a submitted grade
00176             $userids = array();
00177             $gradeforuser = array();
00178             foreach ($grades as $grade) {
00179                 $userids[] = $grade->userid;
00180                 $gradeforuser[$grade->userid] = (float)$grade->grade;
00181             }
00182 
00183             // Now find which groups these users belong in
00184             list($usertest, $params) = $DB->get_in_or_equal($userids);
00185             $params[] = $courseid;
00186             $usergroups = $DB->get_records_sql('
00187                     SELECT gm.id, gm.userid, gm.groupid, g.name
00188                     FROM {groups} g
00189                     LEFT JOIN {groups_members} gm ON g.id = gm.groupid
00190                     WHERE gm.userid ' . $usertest . ' AND g.courseid = ?', $params);
00191 
00192             // Now, iterate the grades again and sum them up for each group
00193             $groupgrades = array();
00194             foreach ($usergroups as $usergroup) {
00195                 if (!isset($groupgrades[$usergroup->groupid])) {
00196                     $groupgrades[$usergroup->groupid] = array(
00197                             'sum' => (float)$gradeforuser[$usergroup->userid],
00198                             'number' => 1,
00199                             'group' => $usergroup->name);
00200                 } else {
00201                     $groupgrades[$usergroup->groupid]['sum'] += $gradeforuser[$usergroup->userid];
00202                     $groupgrades[$usergroup->groupid]['number'] += 1;
00203                 }
00204             }
00205 
00206             foreach($groupgrades as $groupid => $groupgrade) {
00207                 $groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number'];
00208             }
00209 
00210             // Sort groupgrades according to average grade, ascending
00211             uasort($groupgrades, create_function('$a, $b', 'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);'));
00212 
00213             // How many groups do we have with graded member submissions to show?
00214             $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades));
00215             $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest);
00216 
00217             // Collect all the group results we are going to use in $best and $worst
00218             $remaining = $numbest;
00219             $groupgrade = end($groupgrades);
00220             while ($remaining--) {
00221                 $best[key($groupgrades)] = $groupgrade['average'];
00222                 $groupgrade = prev($groupgrades);
00223             }
00224 
00225             $remaining = $numworst;
00226             $groupgrade = reset($groupgrades);
00227             while ($remaining--) {
00228                 $worst[key($groupgrades)] = $groupgrade['average'];
00229                 $groupgrade = next($groupgrades);
00230             }
00231 
00232             // Ready for output!
00233             $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
00234 
00235             if (!$inquiz) {
00236                 // Don't show header and link to the quiz if we ARE at the quiz...
00237                 $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>';
00238             }
00239 
00240             if ($nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL) {
00241                 if (has_capability('moodle/course:managegroups', $context)) {
00242                     $grouplink = $CFG->wwwroot.'/group/overview.php?id='.$courseid.'&amp;group=';
00243                 } else if (has_capability('moodle/course:viewparticipants', $context)) {
00244                     $grouplink = $CFG->wwwroot.'/user/index.php?id='.$courseid.'&amp;group=';
00245                 } else {
00246                     $grouplink = '';
00247                 }
00248             }
00249 
00250             $rank = 0;
00251             if(!empty($best)) {
00252                 $this->content->text .= '<table class="grades"><caption>';
00253                 $this->content->text .= ($numbest == 1?get_string('bestgroupgrade', 'block_quiz_results'):get_string('bestgroupgrades', 'block_quiz_results', $numbest));
00254                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
00255                 foreach($best as $groupid => $averagegrade) {
00256                     switch($nameformat) {
00257                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
00258                         case B_QUIZRESULTS_NAME_FORMAT_ID:
00259                             $thisname = get_string('group');
00260                         break;
00261                         default:
00262                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
00263                             if ($grouplink) {
00264                                 $thisname = '<a href="'.$grouplink.$groupid.'">'.$groupgrades[$groupid]['group'].'</a>';
00265                             } else {
00266                                 $thisname = $groupgrades[$groupid]['group'];
00267                             }
00268                         break;
00269                     }
00270                     $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
00271                     switch($gradeformat) {
00272                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
00273                             $this->content->text .= quiz_format_grade($quiz, $averagegrade).'/'.$quiz->grade;
00274                         break;
00275                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
00276                             $this->content->text .= quiz_format_grade($quiz, $averagegrade);
00277                         break;
00278                         default:
00279                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
00280                             $this->content->text .= round((float)$averagegrade / (float)$quiz->grade * 100).'%';
00281                         break;
00282                     }
00283                     $this->content->text .= '</td></tr>';
00284                 }
00285                 $this->content->text .= '</tbody></table>';
00286             }
00287 
00288             $rank = 0;
00289             if(!empty($worst)) {
00290                 $worst = array_reverse($worst, true);
00291                 $this->content->text .= '<table class="grades"><caption>';
00292                 $this->content->text .= ($numworst == 1?get_string('worstgroupgrade', 'block_quiz_results'):get_string('worstgroupgrades', 'block_quiz_results', $numworst));
00293                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
00294                 foreach($worst as $groupid => $averagegrade) {
00295                     switch($nameformat) {
00296                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
00297                         case B_QUIZRESULTS_NAME_FORMAT_ID:
00298                             $thisname = get_string('group');
00299                         break;
00300                         default:
00301                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
00302                             $thisname = '<a href="'.$CFG->wwwroot.'/course/group.php?group='.$groupid.'&amp;id='.$courseid.'">'.$groupgrades[$groupid]['group'].'</a>';
00303                         break;
00304                     }
00305                     $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
00306                     switch($gradeformat) {
00307                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
00308                             $this->content->text .= quiz_format_grade($quiz, $averagegrade).'/'.$quiz->grade;
00309                         break;
00310                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
00311                             $this->content->text .= quiz_format_grade($quiz, $averagegrade);
00312                         break;
00313                         default:
00314                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
00315                             $this->content->text .= round((float)$averagegrade / (float)$quiz->grade * 100).'%';
00316                         break;
00317                     }
00318                     $this->content->text .= '</td></tr>';
00319                 }
00320                 $this->content->text .= '</tbody></table>';
00321             }
00322             break;
00323 
00324 
00325             case SEPARATEGROUPS:
00326             // This is going to be just like no-groups mode, only we 'll filter
00327             // out the grades from people not in our group.
00328             if (!isloggedin()) {
00329                 // Not logged in, so show nothing
00330                 return $this->content;
00331             }
00332 
00333             $mygroups = groups_get_all_groups($courseid, $USER->id);
00334             if(empty($mygroups)) {
00335                 // Not member of a group, show nothing
00336                 return $this->content;
00337             }
00338 
00339             // Get users from the same groups as me.
00340             list($grouptest, $params) = $DB->get_in_or_equal(array_keys($mygroups));
00341             $mygroupsusers = $DB->get_records_sql_menu(
00342                     'SELECT DISTINCT userid, 1 FROM {groups_members} WHERE groupid ' . $grouptest,
00343                     $params);
00344 
00345             // Filter out the grades belonging to other users, and proceed as if there were no groups
00346             foreach ($grades as $key => $grade) {
00347                 if (!isset($mygroupsusers[$grade->userid])) {
00348                     unset($grades[$key]);
00349                 }
00350             }
00351 
00352             // No break, fall through to the default case now we have filtered the $grades array.
00353             default:
00354             case NOGROUPS:
00355             // Single user mode
00356             $numbest  = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades));
00357             $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest);
00358 
00359             // Collect all the usernames we are going to need
00360             $remaining = $numbest;
00361             $grade = end($grades);
00362             while($remaining--) {
00363                 $best[$grade->userid] = $grade->id;
00364                 $grade = prev($grades);
00365             }
00366 
00367             $remaining = $numworst;
00368             $grade = reset($grades);
00369             while($remaining--) {
00370                 $worst[$grade->userid] = $grade->id;
00371                 $grade = next($grades);
00372             }
00373 
00374             if(empty($best) && empty($worst)) {
00375                 // Nothing to show, for some reason...
00376                 return $this->content;
00377             }
00378 
00379             // Now grab all the users from the database
00380             $userids = array_merge(array_keys($best), array_keys($worst));
00381             $users = $DB->get_records_list('user', 'id', $userids, '', 'id, firstname, lastname, idnumber');
00382 
00383             // Ready for output!
00384 
00385             $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
00386 
00387             if(!$inquiz) {
00388                 // Don't show header and link to the quiz if we ARE at the quiz...
00389                 $this->content->text .= '<h1><a href="'.$CFG->wwwroot.'/mod/quiz/view.php?q='.$quizid.'">'.$quiz->name.'</a></h1>';
00390             }
00391 
00392             $rank = 0;
00393             if(!empty($best)) {
00394                 $this->content->text .= '<table class="grades"><caption>';
00395                 $this->content->text .= ($numbest == 1?get_string('bestgrade', 'block_quiz_results'):get_string('bestgrades', 'block_quiz_results', $numbest));
00396                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
00397                 foreach($best as $userid => $gradeid) {
00398                     switch($nameformat) {
00399                         case B_QUIZRESULTS_NAME_FORMAT_ID:
00400                             $thisname = get_string('user').' '.$users[$userid]->idnumber;
00401                         break;
00402                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
00403                             $thisname = get_string('user');
00404                         break;
00405                         default:
00406                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
00407                             $thisname = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&amp;course='.$courseid.'">'.fullname($users[$userid]).'</a>';
00408                         break;
00409                     }
00410                     $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
00411                     switch($gradeformat) {
00412                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
00413                             $this->content->text .=  quiz_format_grade($quiz, $grades[$gradeid]->grade).'/'.$quiz->grade;
00414                         break;
00415                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
00416                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
00417                         break;
00418                         default:
00419                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
00420                             if ($quiz->grade) {
00421                                 $this->content->text .= round((float)$grades[$gradeid]->grade / (float)$quiz->grade * 100).'%';
00422                             } else {
00423                                 $this->content->text .= '--%';
00424                             }
00425                         break;
00426                     }
00427                     $this->content->text .= '</td></tr>';
00428                 }
00429                 $this->content->text .= '</tbody></table>';
00430             }
00431 
00432             $rank = 0;
00433             if(!empty($worst)) {
00434                 $worst = array_reverse($worst, true);
00435                 $this->content->text .= '<table class="grades"><caption>';
00436                 $this->content->text .= ($numworst == 1?get_string('worstgrade', 'block_quiz_results'):get_string('worstgrades', 'block_quiz_results', $numworst));
00437                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
00438                 foreach($worst as $userid => $gradeid) {
00439                     switch($nameformat) {
00440                         case B_QUIZRESULTS_NAME_FORMAT_ID:
00441                             $thisname = get_string('user').' '.$users[$userid]->idnumber;
00442                         break;
00443                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
00444                             $thisname = get_string('user');
00445                         break;
00446                         default:
00447                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
00448                             $thisname = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$userid.'&amp;course='.$courseid.'">'.fullname($users[$userid]).'</a>';
00449                         break;
00450                     }
00451                     $this->content->text .= '<tr><td>'.(++$rank).'.</td><td>'.$thisname.'</td><td>';
00452                     switch($gradeformat) {
00453                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
00454                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade).'/'.$quiz->grade;
00455                         break;
00456                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
00457                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
00458                         break;
00459                         default:
00460                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
00461                             $this->content->text .= round((float)$grades[$gradeid]->grade / (float)$quiz->grade * 100).'%';
00462                         break;
00463                     }
00464                     $this->content->text .= '</td></tr>';
00465                 }
00466                 $this->content->text .= '</tbody></table>';
00467             }
00468             break;
00469         }
00470 
00471         return $this->content;
00472     }
00473 
00474     function instance_allow_multiple() {
00475         return true;
00476     }
00477 }
00478 
00479 
 All Data Structures Namespaces Files Functions Variables Enumerations