Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * The gradebook outcomes report
  19   *
  20   * @package   gradereport_outcomes
  21   * @copyright 2007 Nicolas Connault
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  include_once('../../../config.php');
  26  require_once($CFG->libdir . '/gradelib.php');
  27  require_once $CFG->dirroot.'/grade/lib.php';
  28  
  29  $courseid = required_param('id', PARAM_INT);                   // course id
  30  
  31  $PAGE->set_url('/grade/report/outcomes/index.php', array('id'=>$courseid));
  32  
  33  if (!$course = $DB->get_record('course', array('id' => $courseid))) {
  34      throw new \moodle_exception('invalidcourseid');
  35  }
  36  
  37  require_login($course);
  38  $context = context_course::instance($course->id);
  39  
  40  require_capability('gradereport/outcomes:view', $context);
  41  
  42  if (empty($CFG->enableoutcomes)) {
  43      redirect(course_get_url($course), get_string('outcomesdisabled', 'core_grades'));
  44  }
  45  
  46  // First make sure we have proper final grades.
  47  grade_regrade_final_grades_if_required($course);
  48  
  49  // Grab all outcomes used in course.
  50  $report_info = array();
  51  $outcomes = grade_outcome::fetch_all_available($courseid);
  52  
  53  // Will exclude grades of suspended users if required.
  54  $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
  55  $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
  56  $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context);
  57  if ($showonlyactiveenrol) {
  58      $suspendedusers = get_suspended_userids($context);
  59  }
  60  
  61  // Get grade_items that use each outcome.
  62  foreach ($outcomes as $outcomeid => $outcome) {
  63      $report_info[$outcomeid]['items'] = $DB->get_records_select('grade_items', "outcomeid = ? AND courseid = ?", array($outcomeid, $courseid));
  64      $report_info[$outcomeid]['outcome'] = $outcome;
  65  
  66      // Get average grades for each item.
  67      if (is_array($report_info[$outcomeid]['items'])) {
  68          foreach ($report_info[$outcomeid]['items'] as $itemid => $item) {
  69              $params = array();
  70              $hidesuspendedsql = '';
  71              if ($showonlyactiveenrol && !empty($suspendedusers)) {
  72                  list($notinusers, $params) = $DB->get_in_or_equal($suspendedusers, SQL_PARAMS_QM, null, false);
  73                  $hidesuspendedsql = ' AND userid ' . $notinusers;
  74              }
  75              $params = array_merge(array($itemid), $params);
  76  
  77              $sql = "SELECT itemid, AVG(finalgrade) AS avg, COUNT(finalgrade) AS count
  78                        FROM {grade_grades}
  79                       WHERE itemid = ?".
  80                       $hidesuspendedsql.
  81                    " GROUP BY itemid";
  82              $info = $DB->get_records_sql($sql, $params);
  83  
  84              if (!$info) {
  85                  unset($report_info[$outcomeid]['items'][$itemid]);
  86                  continue;
  87              } else {
  88                  $info = reset($info);
  89                  $avg = round($info->avg, 2);
  90                  $count = $info->count;
  91              }
  92  
  93              $report_info[$outcomeid]['items'][$itemid]->avg = $avg;
  94              $report_info[$outcomeid]['items'][$itemid]->count = $count;
  95          }
  96      }
  97  }
  98  
  99  $html = '<table class="generaltable boxaligncenter" width="90%" cellspacing="1" cellpadding="5" summary="Outcomes Report">' . "\n";
 100  $html .= '<tr><th class="header c0" scope="col">' . get_string('outcomeshortname', 'grades') . '</th>';
 101  $html .= '<th class="header c1" scope="col">' . get_string('courseavg', 'grades') . '</th>';
 102  $html .= '<th class="header c2" scope="col">' . get_string('sitewide', 'grades') . '</th>';
 103  $html .= '<th class="header c3" scope="col">' . get_string('activities', 'grades') . '</th>';
 104  $html .= '<th class="header c4" scope="col">' . get_string('average', 'grades') . '</th>';
 105  $html .= '<th class="header c5" scope="col">' . get_string('numberofgrades', 'grades') . '</th></tr>' . "\n";
 106  
 107  $row = 0;
 108  foreach ($report_info as $outcomeid => $outcomedata) {
 109      $rowspan = count($outcomedata['items']);
 110      // If there are no items for this outcome, rowspan will equal 0, which is not good.
 111      if ($rowspan == 0) {
 112          $rowspan = 1;
 113      }
 114  
 115      $shortname_html = '<tr class="r' . $row . '"><td class="cell c0" rowspan="' . $rowspan . '">' . $outcomedata['outcome']->shortname . "</td>\n";
 116  
 117      $sitewide = get_string('no');
 118      if (empty($outcomedata['outcome']->courseid)) {
 119          $sitewide = get_string('yes');
 120      }
 121  
 122      $sitewide_html = '<td class="cell c2" rowspan="' . $rowspan . '">' . $sitewide . "</td>\n";
 123  
 124      $outcomedata['outcome']->sum = 0;
 125      $scale = new grade_scale(array('id' => $outcomedata['outcome']->scaleid), false);
 126  
 127      $print_tr = false;
 128      $items_html = '';
 129  
 130      if (!empty($outcomedata['items'])) {
 131          foreach ($outcomedata['items'] as $itemid => $item) {
 132              if ($print_tr) {
 133                  $row++;
 134                  $items_html .= "<tr class=\"r$row\">\n";
 135              }
 136  
 137              $grade_item = new grade_item($item, false);
 138  
 139              if ($item->itemtype == 'mod') {
 140                  $cm = get_coursemodule_from_instance($item->itemmodule, $item->iteminstance, $item->courseid);
 141                  $itemname = '<a href="'.$CFG->wwwroot.'/mod/'.$item->itemmodule.'/view.php?id='.$cm->id.'">'.format_string($cm->name, true, $cm->course).'</a>';
 142              } else {
 143                  $itemname = $grade_item->get_name();
 144              }
 145  
 146              $outcomedata['outcome']->sum += $item->avg;
 147              $gradehtml = $scale->get_nearest_item($item->avg);
 148  
 149              $items_html .= "<td class=\"cell c3\">$itemname</td>"
 150                           . "<td class=\"cell c4\">$gradehtml ($item->avg)</td>"
 151                           . "<td class=\"cell c5\">$item->count</td></tr>\n";
 152              $print_tr = true;
 153          }
 154      } else {
 155          $items_html .= "<td class=\"cell c3\"> - </td><td class=\"cell c4\"> - </td><td class=\"cell c5\"> 0 </td></tr>\n";
 156      }
 157  
 158      // Calculate outcome average.
 159      if (is_array($outcomedata['items'])) {
 160          $count = count($outcomedata['items']);
 161          if ($count > 0) {
 162              $avg = $outcomedata['outcome']->sum / $count;
 163          } else {
 164              $avg = $outcomedata['outcome']->sum;
 165          }
 166          $avg_html = $scale->get_nearest_item($avg) . " (" . round($avg, 2) . ")\n";
 167      } else {
 168          $avg_html = ' - ';
 169      }
 170  
 171      $outcomeavg_html = '<td class="cell c1" rowspan="' . $rowspan . '">' . $avg_html . "</td>\n";
 172  
 173      $html .= $shortname_html . $outcomeavg_html . $sitewide_html . $items_html;
 174      $row++;
 175  }
 176  
 177  $html .= '</table>';
 178  
 179  print_grade_page_head($courseid, 'report', 'outcomes');
 180  
 181  echo $html;
 182  
 183  $event = \gradereport_outcomes\event\grade_report_viewed::create(
 184      array(
 185          'context' => $context,
 186          'courseid' => $courseid,
 187      )
 188  );
 189  $event->trigger();
 190  
 191  echo $OUTPUT->footer();