MDL-66074 gradingform_rubric: Documentation and selectors
authorMathew May <mathewm@hotmail.co.nz>
Mon, 28 Oct 2019 04:56:19 +0000 (12:56 +0800)
committerMathew May <mathewm@hotmail.co.nz>
Wed, 30 Oct 2019 05:03:59 +0000 (13:03 +0800)
grade/grading/form/rubric/amd/build/grades/grader/gradingpanel.min.js.map
grade/grading/form/rubric/amd/src/grades/grader/gradingpanel.js
grade/grading/form/rubric/classes/grades/grader/gradingpanel/external/fetch.php
grade/grading/form/rubric/classes/grades/grader/gradingpanel/external/store.php
grade/grading/form/rubric/db/services.php
grade/grading/form/rubric/lib.php
grade/grading/form/rubric/templates/grades/grader/gradingpanel.mustache
grade/grading/form/rubric/tests/coverage.php
grade/grading/form/rubric/tests/grades_grader_gradingpanel_rubric_external_fetch_test.php
grade/grading/form/rubric/tests/grades_grader_gradingpanel_rubric_external_store_test.php

index 0723bdb..8611812 100644 (file)
Binary files a/grade/grading/form/rubric/amd/build/grades/grader/gradingpanel.min.js.map and b/grade/grading/form/rubric/amd/build/grades/grader/gradingpanel.min.js.map differ
index 90885a9..52307f5 100644 (file)
@@ -29,6 +29,16 @@ import {normaliseResult} from 'core_grades/grades/grader/gradingpanel/normalise'
 // Note: We use jQuery.serializer here until we can rewrite Ajax to use XHR.send()
 import jQuery from 'jquery';
 
+/**
+ * For a given component, contextid, itemname & gradeduserid we can fetch the currently assigned grade.
+ *
+ * @param {String} component
+ * @param {Number} contextid
+ * @param {String} itemname
+ * @param {Number} gradeduserid
+ *
+ * @returns {Promise}
+ */
 export const fetchCurrentGrade = (component, contextid, itemname, gradeduserid) => {
     return fetchMany([{
         methodname: `gradingform_rubric_grader_gradingpanel_fetch`,
@@ -41,7 +51,17 @@ export const fetchCurrentGrade = (component, contextid, itemname, gradeduserid)
     }])[0];
 };
 
-
+/**
+ * For a given component, contextid, itemname & gradeduserid we can store the currently assigned grade in a given form.
+ *
+ * @param {String} component
+ * @param {Number} contextid
+ * @param {String} itemname
+ * @param {Number} gradeduserid
+ * @param {HTMLElement} rootNode
+ *
+ * @returns {Promise}
+ */
 export const storeCurrentGrade = async(component, contextid, itemname, gradeduserid, rootNode) => {
     const form = rootNode.querySelector('form');
 
index 1a9b7e5..c60f421 100644 (file)
@@ -26,6 +26,8 @@ declare(strict_types = 1);
 
 namespace gradingform_rubric\grades\grader\gradingpanel\external;
 
+global $CFG;
+
 use coding_exception;
 use context;
 use core_grades\component_gradeitem as gradeitem;
@@ -38,6 +40,7 @@ use external_value;
 use external_warnings;
 use stdClass;
 use moodle_exception;
+require_once($CFG->dirroot.'/grade/grading/form/rubric/lib.php');
 
 /**
  * Web services relating to fetching of a rubric for the grading panel.
@@ -90,8 +93,6 @@ class fetch extends external_api {
      * @since Moodle 3.8
      */
     public static function execute(string $component, int $contextid, string $itemname, int $gradeduserid): array {
-        global $USER;
-
         [
             'component' => $component,
             'contextid' => $contextid,
@@ -116,7 +117,7 @@ class fetch extends external_api {
         // Fetch the gradeitem instance.
         $gradeitem = gradeitem::instance($component, $context, $itemname);
 
-        if ('rubric' !== $gradeitem->get_advanced_grading_method()) {
+        if (RUBRIC !== $gradeitem->get_advanced_grading_method()) {
             throw new moodle_exception(
                 "The {$itemname} item in {$component}/{$contextid} is not configured for advanced grading with a rubric"
             );
@@ -129,7 +130,7 @@ class fetch extends external_api {
     }
 
     /**
-     * Get the data to be fetched.
+     * Get the data to be fetched and create the structure ready for Mustache.
      *
      * @param gradeitem $gradeitem
      * @param stdClass $gradeduser
@@ -138,6 +139,7 @@ class fetch extends external_api {
     public static function get_fetch_data(gradeitem $gradeitem, stdClass $gradeduser): array {
         global $USER;
 
+        // Set up all the controllers etc that we'll be needing.
         $grade = $gradeitem->get_grade_for_user($gradeduser, $USER);
         $instance = $gradeitem->get_advanced_grading_instance($USER, $grade);
         $controller = $instance->get_controller();
@@ -156,7 +158,9 @@ class fetch extends external_api {
 
         $criterion = [];
         if ($definition->rubric_criteria) {
+            // Iterate over the defined criterion in the rubric and map out what we need to render each item.
             $criterion = array_map(function($criterion) use ($definitionid, $fillings, $context) {
+                // The general structure we'll be returning, we still need to get the remark (if any) and the levels associated.
                 $result = [
                     'id' => $criterion['id'],
                     'description' => self::get_formatted_text(
@@ -168,6 +172,7 @@ class fetch extends external_api {
                     ),
                 ];
 
+                // Do we have an existing grade filling? if so lets get the remark associated to this criteria.
                 $filling = [];
                 if (array_key_exists($criterion['id'], $fillings['criteria'])) {
                     $filling = $fillings['criteria'][$criterion['id']];
@@ -179,7 +184,9 @@ class fetch extends external_api {
                     );
                 }
 
+                // Lets build the levels within a criteria and figure out what needs to go where.
                 $result['levels'] = array_map(function($level) use ($criterion, $filling, $context, $definitionid) {
+                    // The bulk of what'll be returned can be defined easily we'll add to this further down.
                     $result = [
                         'id' => $level['id'],
                         'criterionid' => $criterion['id'],
@@ -194,6 +201,7 @@ class fetch extends external_api {
                         'checked' => null,
                     ];
 
+                    // Consult the grade filling to see if a level has been selected and if it is the current level.
                     if (array_key_exists('levelid', $filling) && $filling['levelid'] == $level['id']) {
                         $result['checked'] = true;
                     }
@@ -201,6 +209,20 @@ class fetch extends external_api {
                     return $result;
                 }, $criterion['levels']);
 
+                $nulllevel = [
+                    'id' => null,
+                    'criterionid' => $criterion['id'],
+                    'score' => '-',
+                    'definition' => 'Not set',
+                    'checked' => null,
+                ];
+                // Consult the grade filling to see if a level has been selected and if it is the current level.
+                if (array_key_exists('levelid', $filling) && $filling['levelid'] == 0) {
+                    $nulllevel['checked'] = true;
+                }
+
+                array_unshift($result['levels'], $nulllevel);
+
                 return $result;
             }, $definition->rubric_criteria);
         }
@@ -241,7 +263,7 @@ class fetch extends external_api {
                         'levels' => new external_multiple_structure(new external_single_structure([
                             'id' => new external_value(PARAM_INT, 'ID of level'),
                             'criterionid' => new external_value(PARAM_INT, 'ID of the criterion this matches to'),
-                            'score' => new external_value(PARAM_INT, 'What this level is worth'),
+                            'score' => new external_value(PARAM_RAW, 'What this level is worth'),
                             'definition' => new external_value(PARAM_RAW, 'Definition of the level'),
                             'checked' => new external_value(PARAM_BOOL, 'Selected flag'),
                         ])),
index dca2d67..67ccfc7 100644 (file)
@@ -26,6 +26,8 @@ declare(strict_types = 1);
 
 namespace gradingform_rubric\grades\grader\gradingpanel\external;
 
+global $CFG;
+
 use coding_exception;
 use context;
 use core_grades\component_gradeitem as gradeitem;
@@ -35,6 +37,7 @@ use external_function_parameters;
 use external_single_structure;
 use external_value;
 use moodle_exception;
+require_once($CFG->dirroot.'/grade/grading/form/rubric/lib.php');
 
 /**
  * Web services relating to storing of a rubric for the grading panel.
@@ -132,7 +135,7 @@ class store extends external_api {
         // Require that this user can save grades.
         $gradeitem->require_user_can_grade($gradeduser, $USER);
 
-        if ('rubric' !== $gradeitem->get_advanced_grading_method()) {
+        if (RUBRIC !== $gradeitem->get_advanced_grading_method()) {
             throw new moodle_exception(
                 "The {$itemname} item in {$component}/{$contextid} is not configured for advanced grading with a rubric"
             );
index e7488e6..08b90a9 100644 (file)
@@ -22,6 +22,8 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die;
+
 $functions = [
     'gradingform_rubric_grader_gradingpanel_fetch' => [
         'classname' => 'gradingform_rubric\\grades\\grader\\gradingpanel\\external\\fetch',
index e81c8ea..361e73b 100644 (file)
@@ -27,6 +27,9 @@ defined('MOODLE_INTERNAL') || die();
 require_once($CFG->dirroot.'/grade/grading/form/lib.php');
 require_once($CFG->dirroot.'/lib/filelib.php');
 
+/** rubric: Used to compare our gradeitem_type against. */
+const RUBRIC = 'rubric';
+
 /**
  * This controller encapsulates the rubric grading logic
  *
index e437c8f..94845f1 100644 (file)
     @template gradingform_rubric/grades/grader/gradingpanel
 
     Classes required for JS:
-    * TODO
+    * none
 
     Data attributes required for JS:
-    * TODO
+    * none
 
     Context variables required for this template:
-    * TODO
+    * instanceid: Instance of the module this grading form belongs too
+    * criteria: A gradeable item in the Marking Guide
+    * id: The ID of the criteria
+    * description: Description of the criteria
+    * levels: The level that a criteria can be graded at
+    * criterionid: The ID of the criteria
+    * checked: Flag for if this is the currently selected level
+    * definition: Definition of the level
+    * remark: Text input for the teacher to relay to the student
 
     Example context (json):
     {
+        "instanceid": "42",
+        "criteria": [
+            {
+                "id": 13,
+                "description": "Show your motivation to rock climbing",
+                "levels": [
+                    {
+                        "criterionid": 13,
+                        "checked": true,
+                        "definition": "Great work!"
+                    }
+                ],
+                "remark": "That's great!"
+            }
+        ]
     }
 }}
 <form id="gradingform_rubric-{{uniqid}}">
     <input type="hidden" name="instanceid" value="{{instanceid}}">
-    <div class="gradingform_rubric-description">{{{teacherdescription}}}</div>
     <div id="rubric-advancedgrading-{{uniqid}}" class="criterion">
         {{#criteria}}
             <div class="d-block mb-2">
index 5a522a0..31da912 100644 (file)
@@ -14,8 +14,6 @@
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-defined('MOODLE_INTERNAL') || die();
-
 /**
  * Coverage information for the gradingform_rubric plugin.
  *
@@ -25,6 +23,8 @@ defined('MOODLE_INTERNAL') || die();
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Coverage information for the gradingform_rubric plugin.
  *
@@ -33,7 +33,7 @@ defined('MOODLE_INTERNAL') || die();
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 return new class extends phpunit_coverage_info {
-    /** @var array The list of folders relative to the plugin root to whitelist in coverage generation. */
+    // Array The list of folders relative to the plugin root to whitelist in coverage generation.
     protected $whitelistfolders = [
         'classes',
         'tests/generator',
index cd4c0f5..ec1ac94 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * Unit tests for core_grades\component_gradeitems;
  *
- * @package   core_grades
+ * @package   gradingform_rubric
  * @category  test
  * @copyright 2019 Mathew May <mathew.solutions>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU Public License
@@ -37,7 +37,7 @@ use moodle_exception;
 /**
  * Unit tests for core_grades\component_gradeitems;
  *
- * @package   core_grades
+ * @package   gradingform_rubric
  * @category  test
  * @copyright 2019 Mathew May <mathew.solutions>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -150,6 +150,9 @@ class fetch_test extends advanced_testcase {
             $levels = $criterion['levels'];
             foreach ($levels as $level) {
                 $levelid = $level['id'];
+                if (!isset($levelid)) {
+                    continue;
+                }
                 $sourcelevel = $sourcecriterion['levels'][$levelid];
 
                 $this->assertArrayHasKey('criterionid', $level);
@@ -235,6 +238,9 @@ class fetch_test extends advanced_testcase {
             $levels = $criterion['levels'];
             foreach ($levels as $level) {
                 $levelid = $level['id'];
+                if (!isset($levelid)) {
+                    continue;
+                }
                 $sourcelevel = $sourcecriterion['levels'][$levelid];
 
                 $this->assertArrayHasKey('criterionid', $level);
@@ -251,9 +257,9 @@ class fetch_test extends advanced_testcase {
 
         }
 
-        $this->assertEquals(1, $criteria[0]['levels'][0]['checked']);
+        $this->assertEquals(1, $criteria[0]['levels'][1]['checked']);
         $this->assertEquals('Too many mistakes. Please try again.', $criteria[0]['remark']);
-        $this->assertEquals(1, $criteria[1]['levels'][2]['checked']);
+        $this->assertEquals(1, $criteria[1]['levels'][3]['checked']);
         $this->assertEquals('Great number of pictures. Well done.', $criteria[1]['remark']);
     }
 
index 6335621..67954a4 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * Unit tests for core_grades\component_gradeitems;
  *
- * @package   core_grades
+ * @package   gradingform_rubric
  * @category  test
  * @copyright 2019 Mathew May <mathew.solutions>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU Public License
@@ -37,7 +37,7 @@ use moodle_exception;
 /**
  * Unit tests for core_grades\component_gradeitems;
  *
- * @package   core_grades
+ * @package   gradingform_rubric
  * @category  test
  * @copyright 2019 Mathew May <mathew.solutions>
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -92,7 +92,6 @@ class store_test extends advanced_testcase {
         $gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum');
 
         $this->expectException(moodle_exception::class);
-        //$this->expectExceptionMessage("not configured for advanced grading with a rubric");
         store::execute('mod_forum', (int) $forum->get_context()->id, 'forum', (int) $student->id, 'formdata');
     }
 
@@ -184,6 +183,9 @@ class store_test extends advanced_testcase {
             $levels = $criterion['levels'];
             foreach ($levels as $level) {
                 $levelid = $level['id'];
+                if (!isset($levelid)) {
+                    continue;
+                }
                 $sourcelevel = $sourcecriterion['levels'][$levelid];
 
                 $this->assertArrayHasKey('criterionid', $level);
@@ -200,9 +202,9 @@ class store_test extends advanced_testcase {
 
         }
 
-        $this->assertEquals(1, $criteria[0]['levels'][0]['checked']);
+        $this->assertEquals(1, $criteria[0]['levels'][1]['checked']);
         $this->assertEquals('Too many mistakes. Please try again.', $criteria[0]['remark']);
-        $this->assertEquals(1, $criteria[1]['levels'][2]['checked']);
+        $this->assertEquals(1, $criteria[1]['levels'][3]['checked']);
         $this->assertEquals('Great number of pictures. Well done.', $criteria[1]['remark']);
     }