first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,69 @@
<?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/>.
/**
* Overview report viewed event.
*
* @package gradereport_overview
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_overview\event;
defined('MOODLE_INTERNAL') || die();
/**
* Overview report viewed event class.
*
* @package gradereport_overview
* @since Moodle 2.8
* @copyright 2014 Adrian Greeve <adrian@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class grade_report_viewed extends \core\event\grade_report_viewed {
/**
* Initialise the event data.
* @return void
*/
protected function init() {
parent::init();
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventgradereportviewed', 'gradereport_overview');
}
/**
* Custom validation.
*
* Throw \coding_exception notice in case of any problems.
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' value must be set.');
}
}
}
+231
View File
@@ -0,0 +1,231 @@
<?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/>.
/**
* External grade report overview API
*
* @package gradereport_overview
* @copyright 2016 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/gradelib.php');
require_once($CFG->dirroot . '/grade/lib.php');
require_once($CFG->dirroot . '/grade/report/overview/lib.php');
/**
* External grade overview report API implementation
*
* @package gradereport_overview
* @copyright 2016 Juan Leyva <juan@moodle.com>
* @category external
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gradereport_overview_external extends external_api {
/**
* Describes the parameters for get_course_grades.
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function get_course_grades_parameters() {
return new external_function_parameters (
array(
'userid' => new external_value(PARAM_INT, 'Get grades for this user (optional, default current)', VALUE_DEFAULT, 0)
)
);
}
/**
* Get the given user courses final grades
*
* @param int $userid get grades for this user (optional, default current)
*
* @return array the grades tables
* @since Moodle 3.2
*/
public static function get_course_grades($userid = 0) {
global $USER;
$warnings = array();
// Validate the parameter.
$params = self::validate_parameters(self::get_course_grades_parameters(),
array(
'userid' => $userid
)
);
$userid = $params['userid'];
if (empty($userid)) {
$userid = $USER->id;
}
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
if ($USER->id != $userid) {
// We must check if the current user can view other users grades.
$user = core_user::get_user($userid, '*', MUST_EXIST);
core_user::require_active_user($user);
require_capability('moodle/grade:viewall', $systemcontext);
}
// We need the site course, and course context.
$course = get_course(SITEID);
$context = context_course::instance($course->id);
// Get the course final grades now.
$gpr = new grade_plugin_return(array('type' => 'report', 'plugin' => 'overview', 'courseid' => $course->id,
'userid' => $userid));
$report = new grade_report_overview($userid, $gpr, $context);
// Force a regrade if required. As this is the overview report, we need to do all courses
// the user is enrolled in, not just $course.
$report->regrade_all_courses_if_needed();
$coursesgrades = $report->setup_courses_data(true);
$grades = array();
foreach ($coursesgrades as $coursegrade) {
$gradeinfo = array(
'courseid' => $coursegrade['course']->id,
'grade' => grade_format_gradevalue($coursegrade['finalgrade'], $coursegrade['courseitem'], true),
'rawgrade' => $coursegrade['finalgrade'],
);
if (isset($coursegrade['rank'])) {
$gradeinfo['rank'] = $coursegrade['rank'];
}
$grades[] = $gradeinfo;
}
$result = array();
$result['grades'] = $grades;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_course_grades return value.
*
* @return external_single_structure
* @since Moodle 3.2
*/
public static function get_course_grades_returns() {
return new external_single_structure(
array(
'grades' => new external_multiple_structure(
new external_single_structure(
array(
'courseid' => new external_value(PARAM_INT, 'Course id'),
'grade' => new external_value(PARAM_RAW, 'Grade formatted'),
'rawgrade' => new external_value(PARAM_RAW, 'Raw grade, not formatted'),
'rank' => new external_value(PARAM_INT, 'Your rank in the course', VALUE_OPTIONAL),
)
)
),
'warnings' => new external_warnings()
)
);
}
/**
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function view_grade_report_parameters() {
return new external_function_parameters(
array(
'courseid' => new external_value(PARAM_INT, 'id of the course'),
'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0)
)
);
}
/**
* Trigger the user report events, do the same that the web interface view of the report
*
* @param int $courseid id of course
* @param int $userid id of the user the report belongs to
* @return array of warnings and status result
* @since Moodle 3.2
* @throws moodle_exception
*/
public static function view_grade_report($courseid, $userid = 0) {
global $USER;
$params = self::validate_parameters(self::view_grade_report_parameters(),
array(
'courseid' => $courseid,
'userid' => $userid
)
);
$warnings = array();
$course = get_course($params['courseid']);
$context = context_course::instance($course->id);
self::validate_context($context);
$userid = $params['userid'];
if (empty($userid)) {
$userid = $USER->id;
} else {
$user = core_user::get_user($userid, '*', MUST_EXIST);
core_user::require_active_user($user);
}
$systemcontext = context_system::instance();
$personalcontext = context_user::instance($userid);
$access = grade_report_overview::check_access($systemcontext, $context, $personalcontext, $course, $userid);
if (!$access) {
throw new moodle_exception('nopermissiontoviewgrades', 'error');
}
grade_report_overview::viewed($context, $course->id, $userid);
$result = array();
$result['status'] = true;
$result['warnings'] = $warnings;
return $result;
}
/**
* Returns description of method result value
*
* @return \core_external\external_description
* @since Moodle 3.2
*/
public static function view_grade_report_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
)
);
}
}
@@ -0,0 +1,46 @@
<?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/>.
/**
* Privacy Subsystem implementation for gradereport_overview.
*
* @package gradereport_overview
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_overview\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for gradereport_overview implementing null_provider.
*
* @copyright 2018 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+40
View File
@@ -0,0 +1,40 @@
<?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/>.
/**
* Defines capabilities for the overview report
*
* @package gradereport_overview
* @copyright 2007 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'gradereport/overview:view' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'user' => CAP_ALLOW
)
)
);
+44
View File
@@ -0,0 +1,44 @@
<?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/>.
/**
* Overview grade report external functions and service definitions.
*
* @package gradereport_overview
* @copyright 2016 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = array(
'gradereport_overview_get_course_grades' => array(
'classname' => 'gradereport_overview_external',
'methodname' => 'get_course_grades',
'description' => 'Get the given user courses final grades',
'type' => 'read',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'gradereport_overview_view_grade_report' => array(
'classname' => 'gradereport_overview_external',
'methodname' => 'view_grade_report',
'description' => 'Trigger the report view event',
'type' => 'write',
'capabilities' => 'gradereport/overview:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
)
);
+45
View File
@@ -0,0 +1,45 @@
<?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/>.
/**
* Grade overview report upgrade steps.
*
* @package gradereport_overview
* @copyright 2017 Simey Lameze <simey@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Function to upgrade grade overview report.
*
* @param int $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_gradereport_overview_upgrade($oldversion) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+204
View File
@@ -0,0 +1,204 @@
<?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/>.
/**
* The gradebook overview report
*
* @package gradereport_overview
* @copyright 2007 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once '../../../config.php';
require_once $CFG->libdir.'/gradelib.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/overview/lib.php';
$courseid = optional_param('id', SITEID, PARAM_INT);
$userid = optional_param('userid', $USER->id, PARAM_INT);
$PAGE->set_url(new moodle_url('/grade/report/overview/index.php', array('id' => $courseid, 'userid' => $userid)));
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new \moodle_exception('invalidcourseid');
}
require_login(null, false);
$PAGE->set_course($course);
$context = context_course::instance($course->id);
$systemcontext = context_system::instance();
$personalcontext = null;
// If we are accessing the page from a site context then ignore this check.
if ($courseid != SITEID) {
require_capability('gradereport/overview:view', $context);
}
if (empty($userid)) {
require_capability('moodle/grade:viewall', $context);
} else {
if (!$DB->get_record('user', array('id'=>$userid, 'deleted'=>0)) or isguestuser($userid)) {
throw new \moodle_exception('invaliduserid');
}
$personalcontext = context_user::instance($userid);
}
if (isset($personalcontext) && $courseid == SITEID) {
$PAGE->set_context($personalcontext);
} else {
$PAGE->set_context($context);
}
if ($userid == $USER->id) {
$settings = $PAGE->settingsnav->find('mygrades', null);
$settings->make_active();
} else if ($courseid != SITEID && $userid) {
// Show some other navbar thing.
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
$PAGE->navigation->extend_for_user($user);
}
$access = grade_report_overview::check_access($systemcontext, $context, $personalcontext, $course, $userid);
if (!$access) {
// no access to grades!
throw new \moodle_exception('nopermissiontoviewgrades', 'error', $CFG->wwwroot.'/course/view.php?id='.$courseid);
}
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'overview', 'courseid'=>$course->id, 'userid'=>$userid));
/// last selected report session tracking
if (!isset($USER->grade_last_report)) {
$USER->grade_last_report = array();
}
$USER->grade_last_report[$course->id] = 'overview';
$actionbar = new \core_grades\output\general_action_bar($context,
new moodle_url('/grade/report/overview/index.php', ['id' => $courseid]), 'report', 'overview');
if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
// Please note this would be extremely slow if we wanted to implement this properly for all teachers.
$groupmode = groups_get_course_groupmode($course); // Groups are being used
$currentgroup = $gpr->groupid;
if (!$currentgroup) { // To make some other functions work better later
$currentgroup = NULL;
}
$isseparategroups = ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context));
if ($isseparategroups and (!$currentgroup)) {
// no separate group access, can view only self
$userid = $USER->id;
$user_selector = false;
} else {
$user_selector = true;
}
if (empty($userid)) {
print_grade_page_head($courseid, 'report', 'overview', false, false, false,
true, null, null, null, $actionbar);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
if ($user_selector) {
$renderer = $PAGE->get_renderer('gradereport_overview');
echo $renderer->graded_users_selector('overview', $course, $userid, $currentgroup, false);
}
// do not list all users
} else { // Only show one user's report
$report = new grade_report_overview($userid, $gpr, $context);
// Make sure we have proper final grades - this report shows grades from other courses, not just the
// selected one, so we need to check and regrade all courses the user is enrolled in.
$report->regrade_all_courses_if_needed(true);
print_grade_page_head($courseid, 'report', 'overview', get_string('pluginname', 'gradereport_overview') .
' - ' . fullname($report->user), false, false, true, null, null,
$report->user, $actionbar);
groups_print_course_menu($course, $gpr->get_return_url('index.php?id='.$courseid, array('userid'=>0)));
if ($user_selector) {
$renderer = $PAGE->get_renderer('gradereport_overview');
echo $renderer->graded_users_selector('overview', $course, $userid, $currentgroup, false);
}
if ($currentgroup and !groups_is_member($currentgroup, $userid)) {
echo $OUTPUT->notification(get_string('groupusernotmember', 'error'));
} else {
if ($report->fill_table()) {
echo '<br />'.$report->print_table(true);
}
}
}
} else { // Non-admins and users viewing from the site context can just see their own report.
// Create a report instance
$report = new grade_report_overview($userid, $gpr, $context);
if (!empty($report->studentcourseids)) {
// If the course id matches the site id then we don't have a course context to work with.
// Display a standard page.
if ($courseid == SITEID) {
$PAGE->set_pagelayout('standard');
$header = get_string('grades', 'grades') . ' - ' . fullname($report->user);
$PAGE->set_title($header);
$PAGE->set_heading(fullname($report->user));
if ($USER->id != $report->user->id) {
$PAGE->navigation->extend_for_user($report->user);
if ($node = $PAGE->settingsnav->get('userviewingsettings'.$report->user->id)) {
$node->forceopen = true;
}
} else if ($node = $PAGE->settingsnav->get('usercurrentsettings', navigation_node::TYPE_CONTAINER)) {
$node->forceopen = true;
}
echo $OUTPUT->header();
if ($report->fill_table(true, true)) {
echo html_writer::tag('h3', get_string('coursesiamtaking', 'grades'));
echo '<br />' . $report->print_table(true);
}
} else { // We have a course context. We must be navigating from the gradebook.
print_grade_page_head($courseid, 'report', 'overview', get_string('pluginname', 'gradereport_overview')
. ' - ' . fullname($report->user), false, false, true, null, null,
$report->user, $actionbar);
if ($report->fill_table()) {
echo '<br />' . $report->print_table(true);
}
}
} else {
$PAGE->set_pagelayout('standard');
$header = get_string('grades', 'grades') . ' - ' . fullname($report->user);
$PAGE->set_title($header);
$PAGE->set_heading(fullname($report->user));
echo $OUTPUT->header();
}
if (count($report->teachercourses)) {
echo html_writer::tag('h3', get_string('coursesiamteaching', 'grades'));
$report->print_teacher_table();
}
if (empty($report->studentcourseids) && empty($report->teachercourses)) {
// We have no report to show the user. Let them know something.
echo $OUTPUT->notification(get_string('noreports', 'grades'), 'notifymessage');
}
}
grade_report_overview::viewed($context, $courseid, $userid);
echo $OUTPUT->footer();
@@ -0,0 +1,29 @@
<?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/>.
/**
* Strings for component 'gradereport_overview', language 'en'
*
* @package gradereport_overview
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['eventgradereportviewed'] = 'Grade overview report viewed';
$string['gradesoverview'] = 'Grades overview';
$string['pluginname'] = 'Overview report';
$string['privacy:metadata'] = 'The Grade overview report only shows data stored in other locations.';
$string['overview:view'] = 'View overview report';
+504
View File
@@ -0,0 +1,504 @@
<?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/>.
/**
* Definition of the grade_overview_report class
*
* @package gradereport_overview
* @copyright 2007 Nicolas Connault
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot . '/grade/report/lib.php');
require_once($CFG->libdir.'/tablelib.php');
/**
* Class providing an API for the overview report building and displaying.
* @uses grade_report
* @package gradereport_overview
*/
class grade_report_overview extends grade_report {
/**
* The user's courses
* @var array $courses
*/
public $courses;
/**
* A flexitable to hold the data.
* @var object $table
*/
public $table;
/**
* Show student ranks within each course.
* @var array $showrank
*/
public $showrank;
/**
* An array of course ids that the user is a student in.
* @var array $studentcourseids
*/
public $studentcourseids;
/**
* An array of courses that the user is a teacher in.
* @var array $teachercourses
*/
public $teachercourses;
/**
* Constructor. Sets local copies of user preferences and initialises grade_tree.
* @param int $userid
* @param object $gpr grade plugin return tracking object
* @param string $context
*/
public function __construct($userid, $gpr, $context) {
global $CFG, $COURSE, $DB, $USER;
parent::__construct($COURSE->id, $gpr, $context);
// Get the user (for full name).
$this->user = $DB->get_record('user', array('id' => $userid));
// Set onlyactive flag to true if the user's viewing his/her report.
$onlyactive = ($this->user->id === $USER->id);
// Load the user's courses.
$this->courses = enrol_get_users_courses($this->user->id, $onlyactive, 'id, shortname, showgrades');
$this->showrank = array();
$this->showrank['any'] = false;
$this->showtotalsifcontainhidden = array();
$this->studentcourseids = array();
$this->teachercourses = array();
$roleids = explode(',', get_config('moodle', 'gradebookroles'));
if ($this->courses) {
foreach ($this->courses as $course) {
$this->showrank[$course->id] = grade_get_setting($course->id, 'report_overview_showrank', !empty($CFG->grade_report_overview_showrank));
if ($this->showrank[$course->id]) {
$this->showrank['any'] = true;
}
$this->showtotalsifcontainhidden[$course->id] = grade_get_setting($course->id, 'report_overview_showtotalsifcontainhidden', $CFG->grade_report_overview_showtotalsifcontainhidden);
$coursecontext = context_course::instance($course->id);
foreach ($roleids as $roleid) {
if (user_has_role_assignment($userid, $roleid, $coursecontext->id)) {
$this->studentcourseids[$course->id] = $course->id;
// We only need to check if one of the roleids has been assigned.
break;
}
}
if (has_capability('moodle/grade:viewall', $coursecontext, $userid)) {
$this->teachercourses[$course->id] = $course;
}
}
}
// base url for sorting by first/last name
$this->baseurl = $CFG->wwwroot.'/grade/overview/index.php?id='.$userid;
$this->pbarurl = $this->baseurl;
$this->setup_table();
}
/**
* Regrades all courses if needed.
*
* If $frontend is true, this may show a progress bar and redirect back to the page (possibly
* several times if multiple courses need it). Otherwise, it will not return until all the
* courses have been updated.
*
* @param bool $frontend True if we are running front-end code and can safely redirect back
*/
public function regrade_all_courses_if_needed(bool $frontend = false): void {
foreach ($this->courses as $course) {
if ($frontend) {
grade_regrade_final_grades_if_required($course);
} else {
grade_regrade_final_grades($course->id);
}
}
}
/**
* Prepares the headers and attributes of the flexitable.
*/
public function setup_table() {
/*
* Table has 3 columns
*| course | final grade | rank (optional) |
*/
// setting up table headers
if ($this->showrank['any']) {
$tablecolumns = array('coursename', 'grade', 'rank');
$tableheaders = array(get_string('coursename', 'grades'),
get_string('gradenoun'),
get_string('rank', 'grades'));
} else {
$tablecolumns = array('coursename', 'grade');
$tableheaders = array(get_string('coursename', 'grades'),
get_string('gradenoun'));
}
$this->table = new flexible_table('grade-report-overview-'.$this->user->id);
$this->table->define_columns($tablecolumns);
$this->table->define_headers($tableheaders);
$this->table->define_baseurl($this->baseurl);
$this->table->set_attribute('cellspacing', '0');
$this->table->set_attribute('id', 'overview-grade');
$this->table->set_attribute('class', 'boxaligncenter generaltable');
$this->table->setup();
}
/**
* Set up the courses grades data for the report.
*
* @param bool $studentcoursesonly Only show courses that the user is a student of.
* @return array of course grades information
*/
public function setup_courses_data($studentcoursesonly) {
global $USER, $DB;
$coursesdata = array();
$numusers = $this->get_numusers(false);
foreach ($this->courses as $course) {
if (!$course->showgrades) {
continue;
}
// If we are only showing student courses and this course isn't part of the group, then move on.
if ($studentcoursesonly && !isset($this->studentcourseids[$course->id])) {
continue;
}
$coursecontext = context_course::instance($course->id);
if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
// The course is hidden and the user isn't allowed to see it.
continue;
}
if (!has_capability('moodle/user:viewuseractivitiesreport', context_user::instance($this->user->id)) &&
((!has_capability('moodle/grade:view', $coursecontext) || $this->user->id != $USER->id) &&
!has_capability('moodle/grade:viewall', $coursecontext))) {
continue;
}
$coursesdata[$course->id]['course'] = $course;
$coursesdata[$course->id]['context'] = $coursecontext;
$canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext);
// Get course grade_item.
$courseitem = grade_item::fetch_course_item($course->id);
// Get the stored grade.
$coursegrade = new grade_grade(array('itemid' => $courseitem->id, 'userid' => $this->user->id));
$coursegrade->grade_item =& $courseitem;
$finalgrade = $coursegrade->finalgrade;
if (!$canviewhidden and !is_null($finalgrade)) {
if ($coursegrade->is_hidden()) {
$finalgrade = null;
} else {
$adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($course->id,
$courseitem,
$finalgrade);
// We temporarily adjust the view of this grade item - because the min and
// max are affected by the hidden values in the aggregation.
$finalgrade = $adjustedgrade['grade'];
$courseitem->grademax = $adjustedgrade['grademax'];
$courseitem->grademin = $adjustedgrade['grademin'];
}
} else {
// We must use the specific max/min because it can be different for
// each grade_grade when items are excluded from sum of grades.
if (!is_null($finalgrade)) {
$courseitem->grademin = $coursegrade->get_grade_min();
$courseitem->grademax = $coursegrade->get_grade_max();
}
}
$coursesdata[$course->id]['finalgrade'] = $finalgrade;
$coursesdata[$course->id]['courseitem'] = $courseitem;
if ($this->showrank['any'] && $this->showrank[$course->id] && !is_null($finalgrade)) {
// Find the number of users with a higher grade.
// Please note this can not work if hidden grades involved :-( to be fixed in 2.0.
$params = array($finalgrade, $courseitem->id);
$sql = "SELECT COUNT(DISTINCT(userid))
FROM {grade_grades}
WHERE finalgrade IS NOT NULL AND finalgrade > ?
AND itemid = ?";
$rank = $DB->count_records_sql($sql, $params) + 1;
$coursesdata[$course->id]['rank'] = $rank;
$coursesdata[$course->id]['numusers'] = $numusers;
}
}
return $coursesdata;
}
/**
* Fill the table for displaying.
*
* @param bool $activitylink If this report link to the activity report or the user report.
* @param bool $studentcoursesonly Only show courses that the user is a student of.
*/
public function fill_table($activitylink = false, $studentcoursesonly = false) {
global $CFG, $DB, $OUTPUT, $USER;
if ($studentcoursesonly && count($this->studentcourseids) == 0) {
return false;
}
// Only show user's courses instead of all courses.
if ($this->courses) {
$coursesdata = $this->setup_courses_data($studentcoursesonly);
// Check whether current user can view all grades of this user - parent most probably.
$viewasuser = $this->course->showgrades && has_any_capability([
'moodle/grade:viewall',
'moodle/user:viewuseractivitiesreport',
], context_user::instance($this->user->id));
foreach ($coursesdata as $coursedata) {
$course = $coursedata['course'];
$coursecontext = $coursedata['context'];
$finalgrade = $coursedata['finalgrade'];
$courseitem = $coursedata['courseitem'];
$coursenamelink = format_string(get_course_display_name_for_list($course), true, ['context' => $coursecontext]);
// Link to the course grade report pages (performing same capability checks as the pages themselves).
if ($activitylink &&
(has_capability('gradereport/' . $CFG->grade_profilereport .':view', $coursecontext) || $viewasuser)) {
$coursenamelink = html_writer::link(new moodle_url('/course/user.php', [
'mode' => 'grade',
'id' => $course->id,
'user' => $this->user->id,
]), $coursenamelink);
} else if (!$activitylink && (has_capability('gradereport/user:view', $coursecontext) || $viewasuser)) {
$coursenamelink = html_writer::link(new moodle_url('/grade/report/user/index.php', [
'id' => $course->id,
'userid' => $this->user->id,
'group' => $this->gpr->groupid,
]), $coursenamelink);
}
$data = [$coursenamelink, grade_format_gradevalue($finalgrade, $courseitem, true)];
if ($this->showrank['any']) {
if ($this->showrank[$course->id] && !is_null($finalgrade)) {
$rank = $coursedata['rank'];
$numusers = $coursedata['numusers'];
$data[] = "$rank/$numusers";
} else {
// No grade, no rank.
// Or this course wants rank hidden.
$data[] = '-';
}
}
$this->table->add_data($data);
}
return true;
} else {
echo $OUTPUT->notification(get_string('notenrolled', 'grades'), 'notifymessage');
return false;
}
}
/**
* Prints or returns the HTML from the flexitable.
* @param bool $return Whether or not to return the data instead of printing it directly.
* @return string
*/
public function print_table($return=false) {
ob_start();
$this->table->print_html();
$html = ob_get_clean();
if ($return) {
return $html;
} else {
echo $html;
}
}
/**
* Print a table to show courses that the user is able to grade.
*/
public function print_teacher_table() {
$table = new html_table();
$table->head = array(get_string('coursename', 'grades'));
$table->data = null;
foreach ($this->teachercourses as $courseid => $course) {
$coursecontext = context_course::instance($course->id);
$coursenamelink = format_string($course->fullname, true, ['context' => $coursecontext]);
$url = new moodle_url('/grade/report/index.php', array('id' => $courseid));
$table->data[] = array(html_writer::link($url, $coursenamelink));
}
echo html_writer::table($table);
}
/**
* Processes the data sent by the form (grades and feedbacks).
* @param array $data
* @return bool Success or Failure (array of errors).
*/
function process_data($data) {
}
function process_action($target, $action) {
}
/**
* This report supports being set as the 'grades' report.
*/
public static function supports_mygrades() {
return true;
}
/**
* Check if the user can access the report.
*
* @param stdClass $systemcontext system context
* @param stdClass $context course context
* @param stdClass $personalcontext personal context
* @param stdClass $course course object
* @param int $userid userid
* @return bool true if the user can access the report
* @since Moodle 3.2
*/
public static function check_access($systemcontext, $context, $personalcontext, $course, $userid) {
global $USER;
$access = false;
if (has_capability('moodle/grade:viewall', $systemcontext)) {
// Ok - can view all course grades.
$access = true;
} else if (has_capability('moodle/grade:viewall', $context)) {
// Ok - can view any grades in context.
$access = true;
} else if ($userid == $USER->id and ((has_capability('moodle/grade:view', $context) and $course->showgrades)
|| $course->id == SITEID)) {
// Ok - can view own course grades.
$access = true;
} else if (has_capability('moodle/grade:viewall', $personalcontext) and $course->showgrades) {
// Ok - can view grades of this user - parent most probably.
$access = true;
} else if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and $course->showgrades) {
// Ok - can view grades of this user - parent most probably.
$access = true;
}
return $access;
}
/**
* Trigger the grade_report_viewed event
*
* @param stdClass $context course context
* @param int $courseid course id
* @param int $userid user id
* @since Moodle 3.2
*/
public static function viewed($context, $courseid, $userid) {
$event = \gradereport_overview\event\grade_report_viewed::create(
array(
'context' => $context,
'courseid' => $courseid,
'relateduserid' => $userid,
)
);
$event->trigger();
}
}
function grade_report_overview_settings_definition(&$mform) {
global $CFG;
//show rank
$options = array(-1 => get_string('default', 'grades'),
0 => get_string('hide'),
1 => get_string('show'));
if (empty($CFG->grade_report_overview_showrank)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
} else {
$options[-1] = get_string('defaultprev', 'grades', $options[1]);
}
$mform->addElement('select', 'report_overview_showrank', get_string('showrank', 'grades'), $options);
$mform->addHelpButton('report_overview_showrank', 'showrank', 'grades');
//showtotalsifcontainhidden
$options = array(-1 => get_string('default', 'grades'),
GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'),
GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') );
if (!array_key_exists($CFG->grade_report_overview_showtotalsifcontainhidden, $options)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
} else {
$options[-1] = get_string('defaultprev', 'grades', $options[$CFG->grade_report_overview_showtotalsifcontainhidden]);
}
$mform->addElement('select', 'report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), $options);
$mform->addHelpButton('report_overview_showtotalsifcontainhidden', 'hidetotalifhiddenitems', 'grades');
}
/**
* Add nodes to myprofile page.
*
* @param \core_user\output\myprofile\tree $tree Tree object
* @param stdClass $user user object
* @param bool $iscurrentuser
* @param stdClass $course Course object
*/
function gradereport_overview_myprofile_navigation(core_user\output\myprofile\tree $tree, $user, $iscurrentuser, $course) {
if (empty($course)) {
// We want to display these reports under the site context.
$course = get_fast_modinfo(SITEID)->get_course();
}
$systemcontext = context_system::instance();
$usercontext = context_user::instance($user->id);
$coursecontext = context_course::instance($course->id);
if (grade_report_overview::check_access($systemcontext, $coursecontext, $usercontext, $course, $user->id)) {
$url = new moodle_url('/grade/report/overview/index.php', array('userid' => $user->id, 'id' => $course->id));
$node = new core_user\output\myprofile\node('reports', 'grades', get_string('gradesoverview', 'gradereport_overview'),
null, $url);
$tree->add_node($node);
}
}
+46
View File
@@ -0,0 +1,46 @@
<?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/>.
/**
* Renderer for the gradebook overview report
*
* @package gradereport_overview
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Custom renderer for the user grade report
*
* To get an instance of this use the following code:
* $renderer = $PAGE->get_renderer('gradereport_overview');
*
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gradereport_overview_renderer extends plugin_renderer_base {
public function graded_users_selector($report, $course, $userid, $groupid, $includeall) {
global $USER;
$select = grade_get_graded_users_select($report, $course, $userid, $groupid, $includeall);
$output = html_writer::tag('div', $this->output->render($select), array('id'=>'graded_users_selector'));
$output .= html_writer::tag('p', '', array('style'=>'page-break-after: always;'));
return $output;
}
}
+37
View File
@@ -0,0 +1,37 @@
<?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/>.
/**
* Defines site settings for the overview gradebook report
*
* @package gradereport_overview
* @copyright 2007 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configcheckbox('grade_report_overview_showrank', get_string('showrank', 'grades'),
get_string('showrank_help', 'grades'), 0));
$settings->add(new admin_setting_configselect('grade_report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'),
get_string('hidetotalifhiddenitems_help', 'grades'), GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN,
array(GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'),
GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'),
GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') )));
}
@@ -0,0 +1,31 @@
@gradereport @gradereport_overview
Feature: Grade overview report should be hidden from suspended enrolments
While viewing the grade overview report
As a student
I should only see courses I am active in
Background:
Given the following "courses" exist:
| fullname | shortname |
| Active course | C1 |
| Suspended course | C2 |
And the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
And the following "course enrolments" exist:
| user | course | role | status |
| student1 | C1 | student | 0 |
| student1 | C2 | student | 1 |
Scenario: Students should not see grades for courses with suspended enrolments
Given I am on the "Active course" "grades > Overview report > View" page logged in as "student1"
Then I should not see "Suspended course" in the "overview-grade" "table"
And I should see "Active course" in the "overview-grade" "table"
Scenario: Admins should see courses with suspended enrolments
Given I log in as "admin"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "Student 1"
When I click on "Grades overview" "link"
Then I should see "Suspended course" in the "overview-grade" "table"
And I should see "Active course" in the "overview-grade" "table"
@@ -0,0 +1,252 @@
<?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/>.
namespace gradereport_overview;
use core_external\external_api;
use externallib_advanced_testcase;
use gradereport_overview_external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* Overview grade report functions unit tests
*
* @package gradereport_overview
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class externallib_test extends externallib_advanced_testcase {
/** @var \stdClass Course 1 record. */
protected $course1;
/** @var \stdClass Course 2 record. */
protected $course2;
/** @var \stdClass To store student user record. */
protected $student1;
/** @var \stdClass To store student user record. */
protected $student2;
/** @var \stdClass To store Teacher user record. */
protected $teacher;
/** @var array To store student 1 and the rawgrade 1. */
protected $student1grade1 = [];
/** @var array To store student 1 and the rawgrade 2. */
protected $student1grade2 = [];
/** @var array To store student 2 and the rawgrade. */
protected $student2grade = [];
/**
* Set up for every test
*/
public function setUp(): void {
global $DB;
$this->resetAfterTest(true);
$s1grade1 = 80;
$s1grade2 = 40;
$s2grade = 60;
$this->course1 = $this->getDataGenerator()->create_course();
$this->course2 = $this->getDataGenerator()->create_course();
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
$this->student1 = $this->getDataGenerator()->create_user();
$this->teacher = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($this->teacher->id, $this->course1->id, $teacherrole->id);
$this->getDataGenerator()->enrol_user($this->student1->id, $this->course1->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($this->student1->id, $this->course2->id, $studentrole->id);
$this->student2 = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($this->student2->id, $this->course1->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($this->student2->id, $this->course2->id, $studentrole->id);
$assignment1 = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $this->course1->id));
$assignment2 = $this->getDataGenerator()->create_module('assign', array('name' => "Test assign", 'course' => $this->course2->id));
$modcontext1 = get_coursemodule_from_instance('assign', $assignment1->id, $this->course1->id);
$modcontext2 = get_coursemodule_from_instance('assign', $assignment2->id, $this->course2->id);
$assignment1->cmidnumber = $modcontext1->id;
$assignment2->cmidnumber = $modcontext2->id;
$this->student1grade1 = array('userid' => $this->student1->id, 'rawgrade' => $s1grade1);
$this->student1grade2 = array('userid' => $this->student1->id, 'rawgrade' => $s1grade2);
$this->student2grade = array('userid' => $this->student2->id, 'rawgrade' => $s2grade);
$studentgrades = array($this->student1->id => $this->student1grade1, $this->student2->id => $this->student2grade);
assign_grade_item_update($assignment1, $studentgrades);
$studentgrades = array($this->student1->id => $this->student1grade2);
assign_grade_item_update($assignment2, $studentgrades);
grade_get_setting($this->course1->id, 'report_overview_showrank', 1);
}
/**
* Test get_course_grades function case student
*/
public function test_get_course_grades_student(): void {
// A user can see his own grades in both courses.
$this->setUser($this->student1);
$studentgrades = gradereport_overview_external::get_course_grades();
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(2, $studentgrades['grades']);
foreach ($studentgrades['grades'] as $grade) {
if ($grade['courseid'] == $this->course1->id) {
$this->assertEquals(80.00, $grade['grade']);
$this->assertEquals(80.0000, $grade['rawgrade']);
$this->assertEquals(1, $grade['rank']);
} else {
$this->assertEquals(40.00, $grade['grade']);
$this->assertEquals(40.0000, $grade['rawgrade']);
$this->assertArrayNotHasKey('rank', $grade);
}
}
// Second student, no grade in one course.
$this->setUser($this->student2);
$studentgrades = gradereport_overview_external::get_course_grades();
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(2, $studentgrades['grades']);
foreach ($studentgrades['grades'] as $grade) {
if ($grade['courseid'] == $this->course1->id) {
$this->assertEquals(60.00, $grade['grade']);
$this->assertEquals(60.0000, $grade['rawgrade']);
$this->assertEquals(2, $grade['rank']);
} else {
$this->assertEquals('-', $grade['grade']);
$this->assertEmpty($grade['rawgrade']);
$this->assertArrayNotHasKey('rank', $grade);
}
}
}
/**
* Test get_course_grades function case admin
*/
public function test_get_course_grades_admin(): void {
// A admin must see all student grades.
$this->setAdminUser();
$studentgrades = gradereport_overview_external::get_course_grades($this->student1->id);
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(2, $studentgrades['grades']);
foreach ($studentgrades['grades'] as $grade) {
if ($grade['courseid'] == $this->course1->id) {
$this->assertEquals(80.00, $grade['grade']);
$this->assertEquals(80.0000, $grade['rawgrade']);
} else {
$this->assertEquals(40.00, $grade['grade']);
$this->assertEquals(40.0000, $grade['rawgrade']);
}
}
$studentgrades = gradereport_overview_external::get_course_grades($this->student2->id);
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(2, $studentgrades['grades']);
// Admins don't see grades.
$studentgrades = gradereport_overview_external::get_course_grades();
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(0, $studentgrades['grades']);
}
/**
* Test get_course_grades function case teacher
*/
public function test_get_course_grades_teacher(): void {
// Teachers don't see grades.
$this->setUser($this->teacher);
$studentgrades = gradereport_overview_external::get_course_grades();
$studentgrades = external_api::clean_returnvalue(gradereport_overview_external::get_course_grades_returns(), $studentgrades);
$this->assertCount(0, $studentgrades['warnings']);
$this->assertCount(0, $studentgrades['grades']);
}
/**
* Test get_course_grades function case incorrect permissions
*/
public function test_get_course_grades_permissions(): void {
// Student can't see other student grades.
$this->setUser($this->student2);
$this->expectException('required_capability_exception');
$studentgrade = gradereport_overview_external::get_course_grades($this->student1->id);
}
/**
* Test view_grade_report function
*/
public function test_view_grade_report(): void {
global $USER;
// Redirect events to the sink, so we can recover them later.
$sink = $this->redirectEvents();
$this->setUser($this->student1);
$result = gradereport_overview_external::view_grade_report($this->course1->id);
$result = external_api::clean_returnvalue(gradereport_overview_external::view_grade_report_returns(), $result);
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Check the event details are correct.
$this->assertInstanceOf('\gradereport_overview\event\grade_report_viewed', $event);
$this->assertEquals(\context_course::instance($this->course1->id), $event->get_context());
$this->assertEquals($USER->id, $event->get_data()['relateduserid']);
$this->setUser($this->teacher);
$result = gradereport_overview_external::view_grade_report($this->course1->id, $this->student1->id);
$result = external_api::clean_returnvalue(gradereport_overview_external::view_grade_report_returns(), $result);
$events = $sink->get_events();
$event = reset($events);
$sink->close();
// Check the event details are correct.
$this->assertInstanceOf('\gradereport_overview\event\grade_report_viewed', $event);
$this->assertEquals(\context_course::instance($this->course1->id), $event->get_context());
$this->assertEquals($this->student1->id, $event->get_data()['relateduserid']);
}
/**
* Test view_grade_report_permissions function
*/
public function test_view_grade_report_permissions(): void {
$this->setUser($this->student2);
$this->expectException('moodle_exception');
$studentgrade = gradereport_overview_external::view_grade_report($this->course1->id, $this->student1->id);
}
}
+125
View File
@@ -0,0 +1,125 @@
<?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/>.
namespace gradereport_overview;
/**
* Overview grade report lib functions unit tests
*
* @package gradereport_overview
* @copyright 2023 The Open University
* @covers \grade_report_overview
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class lib_test extends \advanced_testcase {
/**
* Require the library file we're about to test, and other requirements.
*/
protected function setUp(): void {
global $CFG;
require_once($CFG->dirroot . '/grade/report/overview/lib.php');
require_once($CFG->dirroot . '/grade/querylib.php');
}
/**
* Data provider for true or false value.
*
* @return array Two options, one with true and one with false
*/
public function true_or_false(): array {
return [
[true],
[false]
];
}
/**
* Tests the regrade_all_courses_if_needed function, which is supposed to regrade all the
* courses that the current user is enrolled on (if they need update).
*
* This is tested with both frontend and backend - the frontend option should not actually
* do the progress bar/continue button (which can't be tested from here because it calls exit)
* because these courses are small.
*
* @dataProvider true_or_false
* @param bool $frontend True to use the front-end parameter to the function under test
*/
public function test_regrade_all_courses_if_needed(bool $frontend): void {
global $DB;
$this->resetAfterTest(true);
$generator = $this->getDataGenerator();
// Create 3 courses and a test user. The test user belongs to 2 of them, while another user
// belongs to the other course.
$user = $generator->create_user();
$otheruser = $generator->create_user();
$course1 = $generator->create_course();
$generator->enrol_user($user->id, $course1->id, 'student');
$course2 = $generator->create_course();
$generator->enrol_user($otheruser->id, $course2->id, 'student');
$course3 = $generator->create_course();
$generator->enrol_user($user->id, $course3->id, 'student');
// We need permission to create grades (even though it's a data generator).
$this->setAdminUser();
// Set up each course grade.
foreach ([$course1, $course2, $course3] as $course) {
// Create an assignment and get its grade item.
$assign = $generator->create_module('assign', ['course' => $course->id]);
$modinfo = get_fast_modinfo($course->id);
$cm = $modinfo->get_cm($assign->cmid);
$items = grade_get_grade_items_for_activity($cm, true);
$item = reset($items);
// Set a grade in the assignment, either for the normal test user or the other user
// depending on course.
if ($course === $course2) {
$userid = $otheruser->id;
} else {
$userid = $user->id;
}
$generator->create_grade_grade([
'itemid' => $item->id,
'userid' => $userid,
'teamsubmission' => false,
'attemptnumber' => 0,
'grade' => 50
]);
// Bodge the final grade so that it needs regrading and is set wrong.
$course->gradeitemid = $DB->get_field('grade_items', 'id',
['courseid' => $course->id, 'itemtype' => 'course'], MUST_EXIST);
$DB->set_field('grade_items', 'needsupdate', 1, ['id' => $course->gradeitemid]);
$DB->set_field('grade_grades', 'finalgrade', 25.0, ['itemid' => $course->gradeitemid]);
}
// Construct the overview report and call regrade_all_courses_if_needed.
$gpr = new \stdClass();
$report = new \grade_report_overview($user->id, $gpr, '');
$report->regrade_all_courses_if_needed($frontend);
// This should have regraded courses 1 and 3, but not 2 (because the user doesn't belong).
$this->assertEqualsWithDelta(50.0, $DB->get_field('grade_grades', 'finalgrade',
['itemid' => $course1->gradeitemid]), 1.0);
$this->assertEqualsWithDelta(25.0, $DB->get_field('grade_grades', 'finalgrade',
['itemid' => $course2->gradeitemid]), 1.0);
$this->assertEqualsWithDelta(50.0, $DB->get_field('grade_grades', 'finalgrade',
['itemid' => $course3->gradeitemid]), 1.0);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?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/>.
/**
* Version details for the overview gradebook report
*
* @package gradereport_overview
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'gradereport_overview'; // Full name of the plugin (used for diagnostics)