MDL-45894 navigation: My grades update to overview report.
authorAdrian Greeve <adrian@moodle.com>
Thu, 5 Feb 2015 06:22:34 +0000 (14:22 +0800)
committerAdrian Greeve <adrian@moodle.com>
Fri, 10 Apr 2015 09:17:05 +0000 (17:17 +0800)
Part of MDL-45774

12 files changed:
admin/settings/appearance.php
admin/settings/grades.php
course/user.php
grade/report/lib.php
grade/report/mygrades.php [new file with mode: 0644]
grade/report/overview/index.php
grade/report/overview/lib.php
lang/en/grades.php
lib/adminlib.php
lib/db/upgrade.php
lib/navigationlib.php
user/lib.php

index 70c564f..d6eb80f 100644 (file)
@@ -27,7 +27,8 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { // sp
         'customusermenuitems',
         new lang_string('customusermenuitems', 'admin'),
         new lang_string('configcustomusermenuitems', 'admin'),
-        'messages,message|/message/index.php|message
+        'mygrades,grades|/grade/report/mygrades.php|grades
+messages,message|/message/index.php|message
 myfiles,moodle|/user/files.php|download
 mybadges,badges|/badges/mybadges.php|award',
         PARAM_TEXT,
index 15a429e..2d9ed38 100644 (file)
@@ -75,6 +75,11 @@ if (has_capability('moodle/grade:manage', $systemcontext)
         $temp->add(new admin_setting_special_gradepointmax());
 
         $temp->add(new admin_setting_special_gradepointdefault());
+
+        $temp->add(new admin_setting_my_grades_report());
+
+        $temp->add(new admin_setting_configtext('gradereport_mygradeurl', new lang_string('externalurl', 'grades'),
+                new lang_string('externalurl_desc', 'grades'), null));
     }
     $ADMIN->add('grades', $temp);
 
index 8b68c77..3320c3e 100644 (file)
@@ -124,10 +124,24 @@ $PAGE->navigation->extend_for_user($user);
 $PAGE->navigation->set_userid_for_parent_checks($user->id); // see MDL-25805 for reasons and for full commit reference for reversal when fixed.
 $PAGE->set_title("$course->shortname: $stractivityreport ($mode)");
 $PAGE->set_heading($course->fullname);
-echo $OUTPUT->header();
 
 switch ($mode) {
     case "grade":
+        // Change the navigation to point to the my grade node (If we are a student).
+        if ($USER->id == $user->id) {
+            require_once($CFG->dirroot . '/user/lib.php');
+            // Get the correct 'My grades' url to point to.
+            $activeurl = user_mygrades_url();
+            $PAGE->navigation->override_active_url($activeurl);
+            $activenode = $PAGE->navbar->add($course->shortname);
+            $activenode->make_active();
+            // Find the course node and collapse it.
+            $coursenode = $PAGE->navigation->find($course->id, navigation_node::TYPE_COURSE);
+            $coursenode->collapse = true;
+            $coursenode->make_inactive();
+        }
+        echo $OUTPUT->header();
+
         if (empty($CFG->grade_profilereport) or !file_exists($CFG->dirroot.'/grade/report/'.$CFG->grade_profilereport.'/lib.php')) {
             $CFG->grade_profilereport = 'user';
         }
@@ -144,6 +158,8 @@ switch ($mode) {
         break;
     default:
         // can not be reached ;-)
+        // But just incase let's not break the navigation.
+        echo $OUTPUT->header();
 }
 
 
index b0aa35b..bd30489 100644 (file)
@@ -353,6 +353,13 @@ abstract class grade_report {
         return $count;
     }
 
+    /**
+     * Shows support for being used as a 'My grades' report.
+     */
+    public static function supports_mygrades() {
+        return false;
+    }
+
     /**
      * Sets up this object's group variables, mainly to restrict the selection of users to display.
      */
diff --git a/grade/report/mygrades.php b/grade/report/mygrades.php
new file mode 100644 (file)
index 0000000..876e34b
--- /dev/null
@@ -0,0 +1,33 @@
+<?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/>.
+
+/**
+ * Redirects the user to the default grade report.
+ *
+ * @package   core_grades
+ * @copyright 2015 Adrian Greeve <adrian@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once('../../config.php');
+require_once($CFG->dirroot . '/user/lib.php');
+
+defined('MOODLE_INTERNAL') || die();
+
+// Get the url to redirect to.
+$url = user_mygrades_url();
+// Redirect to that page.
+redirect($url);
index 3723f24..c8c11ed 100644 (file)
@@ -27,20 +27,25 @@ require_once $CFG->libdir.'/gradelib.php';
 require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->dirroot.'/grade/report/overview/lib.php';
 
-$courseid = required_param('id', PARAM_INT);
+$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)));
+$PAGE->set_url(new moodle_url('/grade/report/overview/index.php', array('id' => $courseid, 'userid' => $userid)));
 
-/// basic access checks
 if (!$course = $DB->get_record('course', array('id' => $courseid))) {
     print_error('nocourseid');
 }
-require_login($course);
+require_login(null, false);
 
 $context = context_course::instance($course->id);
 $systemcontext = context_system::instance();
-require_capability('gradereport/overview:view', $context);
+$personalcontext = null;
+$PAGE->set_context($context);
+
+// 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);
@@ -49,6 +54,7 @@ if (empty($userid)) {
     if (!$DB->get_record('user', array('id'=>$userid, 'deleted'=>0)) or isguestuser($userid)) {
         print_error('invaliduserid');
     }
+    $personalcontext = context_user::instance($userid);
 }
 
 $access = false;
@@ -60,12 +66,16 @@ if (has_capability('moodle/grade:viewall', $systemcontext)) {
     // Ok - can view any grades in context.
     $access = true;
 
-} else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
+} else if ($userid == $USER->id and ((has_capability('moodle/grade:view', $context) and $course->showgrades)
+        || $courseid == SITEID)) {
     // Ok - can view own course grades.
     $access = true;
 
-} else if (has_capability('moodle/grade:viewall', context_user::instance($userid)) and $course->showgrades) {
-    // Ok - can view grades of this user- parent most probably.
+} 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;
 }
 
@@ -86,7 +96,7 @@ $USER->grade_last_report[$course->id] = 'overview';
 //first make sure we have proper final grades - this must be done before constructing of the grade tree
 grade_regrade_final_grades($courseid);
 
-if (has_capability('moodle/grade:viewall', $context)) {
+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 = groups_get_course_group($course, true);
@@ -135,16 +145,38 @@ if (has_capability('moodle/grade:viewall', $context)) {
             }
         }
     }
-} else { //Non-admins will see just their own report
+} 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);
 
-    // print the page
-    print_grade_page_head($courseid, 'report', 'overview', get_string('pluginname', 'gradereport_overview'). ' - '.fullname($report->user));
+    // 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('mygrades', 'grades'). ' - '.fullname($report->user);
+        $PAGE->set_title($header);
+        $PAGE->set_heading($header);
+
+        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;
+        }
 
-    if ($report->fill_table()) {
-        echo '<br />'.$report->print_table(true);
+        echo $OUTPUT->header();
+        if ($report->fill_table(true)) {
+            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));
+        if ($report->fill_table()) {
+            echo '<br />'.$report->print_table(true);
+        }
     }
 }
 
index a68b6e9..8d03910 100644 (file)
@@ -134,7 +134,12 @@ class grade_report_overview extends grade_report {
         $this->table->setup();
     }
 
-    public function fill_table() {
+    /**
+     * Fill the table for displaying.
+     *
+     * @param bool $activitylink If this report link to the activity report or the user report.
+     */
+    public function fill_table($activitylink = false) {
         global $CFG, $DB, $OUTPUT, $USER;
 
         // Only show user's courses instead of all courses.
@@ -153,13 +158,21 @@ class grade_report_overview extends grade_report {
                     continue;
                 }
 
-                if ((!has_capability('moodle/grade:view', $coursecontext) || $this->user->id != $USER->id) &&
-                        !has_capability('moodle/grade:viewall', $coursecontext)) {
+                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;
                 }
 
-                $courseshortname = format_string(get_course_display_name_for_list($course), true, array('context' => $coursecontext));
-                $courselink = html_writer::link(new moodle_url('/grade/report/user/index.php', array('id' => $course->id, 'userid' => $this->user->id)), $courseshortname);
+                $coursename = format_string(get_course_display_name_for_list($course), true, array('context' => $coursecontext));
+                // Link to the activity report version of the user grade report.
+                if ($activitylink) {
+                    $courselink = html_writer::link(new moodle_url('/course/user.php', array('mode' => 'grade', 'id' => $course->id,
+                        'user' => $this->user->id)), $coursename);
+                } else {
+                    $courselink = html_writer::link(new moodle_url('/grade/report/user/index.php', array('id' => $course->id,
+                        'userid' => $this->user->id)), $coursename);
+                }
                 $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext);
 
                 // Get course grade_item
@@ -221,7 +234,7 @@ class grade_report_overview extends grade_report {
             return true;
 
         } else {
-            echo $OUTPUT->notification(get_string('nocourses', 'grades'));
+            echo $OUTPUT->notification(get_string('notenrolled', 'grades'), 'notifymessage');
             return false;
         }
     }
@@ -251,6 +264,13 @@ class grade_report_overview extends grade_report {
     }
     function process_action($target, $action) {
     }
+
+    /**
+     * This report supports being set as the 'my grades' report.
+     */
+    public static function supports_mygrades() {
+        return true;
+    }
 }
 
 function grade_report_overview_settings_definition(&$mform) {
index a15d522..0c086c2 100644 (file)
@@ -206,6 +206,8 @@ $string['exportsettings'] = 'Export settings';
 $string['exportonlyactive'] = 'Exclude suspended users';
 $string['exportonlyactive_help'] = 'Only include students in the export whose enrolment is active and has not been suspended';
 $string['exportto'] = 'Export to';
+$string['externalurl'] = 'External URL';
+$string['externalurl_desc'] = 'Specify an external url to use for the my grade page. My grades must be set to External URL.';
 $string['extracreditvalue'] = 'Extra credit value for {$a}';
 $string['extracreditwarning'] = 'Note: Setting all items for a category to extra credit will effectively remove them from the grade calculation. Since there will be no point total';
 $string['feedback'] = 'Feedback';
@@ -455,6 +457,8 @@ $string['movingelement'] = 'Moving {$a}';
 $string['multfactor'] = 'Multiplicator';
 $string['multfactorvalue'] = 'Multiplicator value for {$a}';
 $string['multfactor_help'] = 'The multiplicator is the factor by which all grades for this grade item will be multiplied, with a maximum value of the maximum grade. For example, if the multiplicator is 2 and the maximum grade is 100, then all grades less than 50 are multiplied by 2, and all grades 50 and above are changed to 100.';
+$string['mygrades'] = 'My grades';
+$string['mygrades_desc'] = 'This sets the "My grades" page in the user menu.';
 $string['mypreferences'] = 'My preferences';
 $string['myreportpreferences'] = 'My report preferences';
 $string['navmethod'] = 'Navigation method';
@@ -485,6 +489,7 @@ $string['noscales'] = 'Outcomes must be linked to a course scale or global scale
 $string['noselectedcategories'] = 'no categories were selected.';
 $string['noselecteditems'] = 'no items were selected.';
 $string['notteachererror'] = 'You must be a teacher to use this feature.';
+$string['notenrolled'] = 'You are currently not enrolled in any courses.';
 $string['nousersloaded'] = 'No users loaded';
 $string['numberofgrades'] = 'Number of grades';
 $string['onascaleof'] = 'on a scale of {$a->grademin} to {$a->grademax}';
index 37da3db..e67ebe1 100644 (file)
@@ -5200,6 +5200,52 @@ class admin_setting_grade_profilereport extends admin_setting_configselect {
     }
 }
 
+/**
+ * Provides a selection of grade reports to be used for "my grades".
+ *
+ * @copyright 2015 Adrian Greeve <adrian@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class admin_setting_my_grades_report extends admin_setting_configselect {
+
+    /**
+     * Calls parent::__construct with specific arguments.
+     */
+    public function __construct() {
+        parent::__construct('grade_mygrades_report', new lang_string('mygrades', 'grades'),
+                new lang_string('mygrades_desc', 'grades'), 'overview', null);
+    }
+
+    /**
+     * Loads an array of choices for the configselect control.
+     *
+     * @return bool always returns true.
+     */
+    public function load_choices() {
+        global $CFG; // Remove this line and behold the horror of behat test failures!
+        $this->choices = array();
+        foreach (core_component::get_plugin_list('gradereport') as $plugin => $plugindir) {
+            if (file_exists($plugindir . '/lib.php')) {
+                require_once($plugindir . '/lib.php');
+                // Check to see if the class exists. Check the correct plugin convention first.
+                if (class_exists('gradereport_' . $plugin)) {
+                    $classname = 'gradereport_' . $plugin;
+                } else if (class_exists('grade_report_' . $plugin)) {
+                    // We are using the old plugin naming convention.
+                    $classname = 'grade_report_' . $plugin;
+                } else {
+                    continue;
+                }
+                if ($classname::supports_mygrades()) {
+                    $this->choices[$plugin] = get_string('pluginname', 'gradereport_' . $plugin);
+                }
+            }
+        }
+        // Add an option to specify an external url.
+        $this->choices['external'] = get_string('externalurl', 'grades');
+        return true;
+    }
+}
 
 /**
  * Special class for register auth selection
index 5ee7f94..8bd1031 100644 (file)
@@ -4304,5 +4304,13 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2015040700.01);
     }
 
+    if ($oldversion < 2015040800.01) {
+        // Add "My grades" to the user menu.
+        $newconfig = "mygrades,grades|/grade/report/mygrades.php|grades\n" . $CFG->customusermenuitems;
+        set_config('customusermenuitems', $newconfig);
+
+        upgrade_main_savepoint(true, 2015040800.01);
+    }
+
     return true;
 }
index 3dafc2b..431be6a 100644 (file)
@@ -2267,6 +2267,22 @@ class global_navigation extends navigation_node {
             $usernode->add(get_string('notes', 'notes'), $url);
         }
 
+        // Show the my grades node.
+        if (($issitecourse && $iscurrentuser) || has_capability('moodle/user:viewdetails', $usercontext)) {
+            require_once($CFG->dirroot . '/user/lib.php');
+            // Set the grades node to link to the "My grades" page.
+            if ($course->id == SITEID) {
+                $url = user_mygrades_url($user->id, $course->id);
+            } else { // Otherwise we are in a course and should redirect to the user grade report (Activity report version).
+                $url = new moodle_url('/course/user.php', array('mode' => 'grade', 'id' => $course->id, 'user' => $user->id));
+            }
+            if ($USER->id != $user->id) {
+                $usernode->add(get_string('grades', 'grades'), $url);
+            } else {
+                $usernode->add(get_string('mygrades', 'grades'), $url);
+            }
+        }
+
         // If the user is the current user add the repositories for the current user
         $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
         if ($iscurrentuser) {
@@ -3804,18 +3820,6 @@ class settings_navigation extends navigation_node {
         $reportavailable = false;
         if (has_capability('moodle/grade:viewall', $coursecontext)) {
             $reportavailable = true;
-        } else if (!empty($course->showgrades)) {
-            $reports = core_component::get_plugin_list('gradereport');
-            if (is_array($reports) && count($reports)>0) {     // Get all installed reports
-                arsort($reports); // user is last, we want to test it first
-                foreach ($reports as $plugin => $plugindir) {
-                    if (has_capability('gradereport/'.$plugin.':view', $coursecontext)) {
-                        //stop when the first visible plugin is found
-                        $reportavailable = true;
-                        break;
-                    }
-                }
-            }
         }
         if ($reportavailable) {
             $url = new moodle_url('/grade/report/index.php', array('id'=>$course->id));
@@ -4324,30 +4328,7 @@ class settings_navigation extends navigation_node {
         foreach ($reports as $reportfunction) {
             $reportfunction($reporttab, $user, $course);
         }
-        $anyreport = has_capability('moodle/user:viewuseractivitiesreport', $usercontext);
-        if ($anyreport || ($course->showreports && $currentuser)) {
-            // Add grade hardcoded grade report if necessary.
-            $gradeaccess = false;
-            if (has_capability('moodle/grade:viewall', $coursecontext)) {
-                // Can view all course grades.
-                $gradeaccess = true;
-            } else if ($course->showgrades) {
-                if ($currentuser && has_capability('moodle/grade:view', $coursecontext)) {
-                    // Can view own grades.
-                    $gradeaccess = true;
-                } else if (has_capability('moodle/grade:viewall', $usercontext)) {
-                    // Can view grades of this user - parent most probably.
-                    $gradeaccess = true;
-                } else if ($anyreport) {
-                    // Can view grades of this user - parent most probably.
-                    $gradeaccess = true;
-                }
-            }
-            if ($gradeaccess) {
-                $reporttab->add(get_string('grade'), new moodle_url('/course/user.php', array('mode'=>'grade', 'id'=>$course->id,
-                        'user'=>$usercontext->instanceid)));
-            }
-        }
+
         // Check the number of nodes in the report node... if there are none remove the node
         $reporttab->trim_if_empty();
 
index 8e3dbab..296da8e 100644 (file)
@@ -674,6 +674,11 @@ function user_convert_text_to_menu_items($text, $page) {
             $bits[1] = null;
             $child->itemtype = "invalid";
         } else {
+            // Nasty hack to replace the my grades with the direct url.
+            if (strpos($bits[1], '/grade/report/mygrades.php') !== false) {
+                $bits[1] = user_mygrades_url();
+            }
+
             // Make sure the url is a moodle url.
             $bits[1] = new moodle_url(trim($bits[1]));
         }
@@ -1023,3 +1028,30 @@ function user_list_view($course, $context) {
     ));
     $event->trigger();
 }
+
+/**
+ * Returns the url to use for the "My grades" link in the user navigation.
+ *
+ * @param int $userid The user's ID.
+ * @param int $courseid The course ID if available.
+ * @return mixed A URL to be directed to for "My grades".
+ */
+function user_mygrades_url($userid = null, $courseid = SITEID) {
+    global $CFG, $USER;
+    $url = null;
+    if (isset($CFG->grade_mygrades_report) && $CFG->grade_mygrades_report != 'external') {
+        if (isset($userid) && $USER->id != $userid) {
+            // Send to the gradebook report.
+            $url = new moodle_url('/grade/report/' . $CFG->grade_mygrades_report . '/index.php',
+                    array('id' => $courseid, 'userid' => $userid));
+        } else {
+            $url = new moodle_url('/grade/report/' . $CFG->grade_mygrades_report . '/index.php');
+        }
+    } else if (isset($CFG->grade_mygrades_report) && $CFG->grade_mygrades_report == 'external'
+            && !empty($CFG->gradereport_mygradeurl)) {
+        $url = $CFG->gradereport_mygradeurl;
+    } else {
+        $url = $CFG->wwwroot;
+    }
+    return $url;
+}