From bb140c20cff33968a6e64055e040bfed6e0e18a4 Mon Sep 17 00:00:00 2001
From: Gordon Bateson <gordonbateson@gmail.com>
Date: Sat, 23 Jan 2016 12:31:09 +0900
Subject: [PATCH] MDL-79863 qtype_ordering: qtype_ordering add new grading
 type: LONGEST_CONTIGUOUS_SUBSET

---
 question/type/ordering/edit_ordering_form.php |  37 ++-----
 .../type/ordering/lang/en/qtype_ordering.php  |   6 +-
 question/type/ordering/question.php           | 103 +++++++++++++++---
 question/type/ordering/questiontype.php       |   7 +-
 question/type/ordering/renderer.php           |  64 +++++------
 question/type/ordering/version.php            |   4 +-
 6 files changed, 135 insertions(+), 86 deletions(-)

diff --git a/question/type/ordering/edit_ordering_form.php b/question/type/ordering/edit_ordering_form.php
index 2a0c50b37b6..fea04fb691c 100644
--- a/question/type/ordering/edit_ordering_form.php
+++ b/question/type/ordering/edit_ordering_form.php
@@ -23,9 +23,11 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-
+/** Prevent direct access to this script */
 defined('MOODLE_INTERNAL') || die();
 
+/** Include required files */
+require_once($CFG->dirroot.'/question/type/ordering/question.php');
 
 /**
  * Ordering editing form definition
@@ -42,13 +44,6 @@ class qtype_ordering_edit_form extends question_edit_form {
     const NUM_ANS_MIN     =  3;
     const NUM_ANS_ADD     =  3;
 
-    const ABSOLUTE_POSITION = 0;
-    const RELATIVE_NEXT_EXCLUDE_LAST = 1;
-    const RELATIVE_NEXT_INCLUDE_LAST = 2;
-    const RELATIVE_ONE_PREVIOUS_AND_NEXT = 3;
-    const RELATIVE_ALL_PREVIOUS_AND_NEXT = 4;
-    const LONGEST_ORDERED_SUBSET = 5;
-
     // this functionality is currently disabled
     // because it is not fully functional
     protected $use_editor_for_answers = true;
@@ -73,10 +68,7 @@ class qtype_ordering_edit_form extends question_edit_form {
         // layouttype
         $name = 'layouttype';
         $label = get_string($name, $plugin);
-        $options = array(
-            0 => get_string('vertical', $plugin),
-            1 => get_string('horizontal', $plugin)
-        );
+        $options = qtype_ordering_question::get_layout_types();
         $mform->addElement('select', $name, $label, $options);
         $mform->addHelpButton($name, $name, $plugin);
         $mform->setDefault($name, 0);
@@ -84,11 +76,7 @@ class qtype_ordering_edit_form extends question_edit_form {
         // selecttype
         $name = 'selecttype';
         $label = get_string($name, $plugin);
-        $options = array(
-            0 => get_string('selectall', $plugin),
-            1 => get_string('selectrandom', $plugin),
-            2 => get_string('selectcontiguous', $plugin)
-        );
+        $options = qtype_ordering_question::get_select_types();
         $mform->addElement('select', $name, $label, $options);
         $mform->addHelpButton($name, $name, $plugin);
         $mform->setDefault($name, 0);
@@ -108,14 +96,7 @@ class qtype_ordering_edit_form extends question_edit_form {
         // gradingtype
         $name = 'gradingtype';
         $label = get_string($name, $plugin);
-        $options = array(
-            self::ABSOLUTE_POSITION => get_string('absoluteposition', $plugin),
-            self::RELATIVE_NEXT_EXCLUDE_LAST => get_string('relativenextexcludelast', $plugin),
-            self::RELATIVE_NEXT_INCLUDE_LAST => get_string('relativenextincludelast', $plugin),
-            self::RELATIVE_ONE_PREVIOUS_AND_NEXT => get_string('relativeonepreviousandnext', $plugin),
-            self::RELATIVE_ALL_PREVIOUS_AND_NEXT => get_string('relativeallpreviousandnext', $plugin),
-            self::LONGEST_ORDERED_SUBSET => get_string('longestorderedsubset', $plugin)
-        );
+        $options = qtype_ordering_question::get_grading_types();
         $mform->addElement('select', $name, $label, $options);
         $mform->addHelpButton($name, $name, $plugin);
         $mform->setDefault($name, 0);
@@ -315,14 +296,14 @@ class qtype_ordering_edit_form extends question_edit_form {
         if (isset($question->options->layouttype)) {
             $question->layouttype = $question->options->layouttype;
         } else {
-            $question->layouttype = 0;
+            $question->layouttype = qtype_ordering_question::LAYOUT_VERTICAL;
         }
 
         // selecttype
         if (isset($question->options->selecttype)) {
             $question->selecttype = $question->options->selecttype;
         } else {
-            $question->selecttype = 0;
+            $question->selecttype = qtype_ordering_question::SELECT_ALL;
         }
 
         // selectcount
@@ -336,7 +317,7 @@ class qtype_ordering_edit_form extends question_edit_form {
         if (isset($question->options->gradingtype)) {
             $question->gradingtype = $question->options->gradingtype;
         } else {
-            $question->gradingtype = 0;
+            $question->gradingtype = qtype_ordering_question::GRADING_ABSOLUTE_POSITION;
         }
 
         return $question;
diff --git a/question/type/ordering/lang/en/qtype_ordering.php b/question/type/ordering/lang/en/qtype_ordering.php
index 9344ebabec7..cc87a44fb42 100644
--- a/question/type/ordering/lang/en/qtype_ordering.php
+++ b/question/type/ordering/lang/en/qtype_ordering.php
@@ -41,10 +41,14 @@ $string['gradingtype_help'] = 'Choose the type of grading calculation.
 : An item is considered correct if it is preceded by all the same items as it is in the correct answer, and it is followed by all the same items as it is in the correct answer. The order of the previous items does not matter, and nor does the order of the following items. Thus, if ***n*** items are displayed to the student, the number of marks available for each item is ***(n - 1)***, and the highest mark availabe for the question is ***n x (n - 1)***, which is the same as ***(n² - n)***.
 
 **Longest ordered subset**
-: The grade is the number of items in the longest ordered subset of items. The highest possible grade is the same as the number of items displayed. A subset must have at least two items. Subsets do not need to start at the first item (but they can) and they do not need to be contiguous (but they can be). Where there are multiple subsets of equal length, items in the subset that is found first, when searching from left to right, will be displayed as correct. Other items will be marked as incorrect.';
+: The grade is the number of items in the longest ordered subset of items. The highest possible grade is the same as the number of items displayed. A subset must have at least two items. Subsets do not need to start at the first item (but they can) and they do not need to be contiguous (but they can be). Where there are multiple subsets of equal length, items in the subset that is found first, when searching from left to right, will be displayed as correct. Other items will be marked as incorrect.
+
+**Longest contiguous subset**
+: The grade is the number of items in the longest contiguous subset of items. The highest possible grade is the same as the number of items displayed. A subset must have at least two items. Subsets do not need to start at the first item (but they can) and they MUST BE CONTIGUOUS. Where there are multiple subsets of equal length, items in the subset that is found first, when searching from left to right, will be displayed as correct. Other items will be marked as incorrect.';
 $string['horizontal'] = 'Horizontal';
 $string['layouttype_help'] = 'Choose whether to display the items vertically or horizontally.';
 $string['layouttype'] = 'Layout of items';
+$string['longestcontiguoussubset'] = 'Longest contiguous subset';
 $string['longestorderedsubset'] = 'Longest ordered subset';
 $string['noresponsedetails'] = 'Sorry, no details of the response to this question are available.';
 $string['noscore'] = 'No score';
diff --git a/question/type/ordering/question.php b/question/type/ordering/question.php
index e08331c5da9..dcbdd0013b0 100644
--- a/question/type/ordering/question.php
+++ b/question/type/ordering/question.php
@@ -23,6 +23,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+/** Prevent direct access to this script */
 defined('MOODLE_INTERNAL') || die();
 
 /**
@@ -33,6 +34,21 @@ defined('MOODLE_INTERNAL') || die();
  */
 class qtype_ordering_question extends question_graded_automatically {
 
+    const SELECT_ALL        = 0;
+    const SELECT_RANDOM     = 1;
+    const SELECT_CONTIGUOUS = 2;
+
+    const LAYOUT_VERTICAL   = 0;
+    const LAYOUT_HORIZONTAL = 1;
+
+    const GRADING_ABSOLUTE_POSITION              = 0;
+    const GRADING_RELATIVE_NEXT_EXCLUDE_LAST     = 1;
+    const GRADING_RELATIVE_NEXT_INCLUDE_LAST     = 2;
+    const GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT = 3;
+    const GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT = 4;
+    const GRADING_LONGEST_ORDERED_SUBSET         = 5;
+    const GRADING_LONGEST_CONTIGUOUS_SUBSET      = 6;
+
     /** fields from "qtype_ordering_options" */
     public $correctfeedback;
     public $correctfeedbackformat;
@@ -156,7 +172,7 @@ class qtype_ordering_question extends question_graded_automatically {
         $options = $this->get_ordering_options();
         switch ($options->gradingtype) {
 
-            case 0: // ABSOLUTE_POSITION
+            case self::GRADING_ABSOLUTE_POSITION:
                 $correctresponse = $this->correctresponse;
                 $currentresponse = $this->currentresponse;
                 foreach ($correctresponse as $position => $answerid) {
@@ -169,8 +185,8 @@ class qtype_ordering_question extends question_graded_automatically {
                 }
                 break;
 
-            case 1: // RELATIVE_NEXT_EXCLUDE_LAST
-            case 2: // RELATIVE_NEXT_INCLUDE_LAST
+            case self::GRADING_RELATIVE_NEXT_EXCLUDE_LAST:
+            case self::GRADING_RELATIVE_NEXT_INCLUDE_LAST:
                 $currentresponse = $this->get_next_answerids($this->currentresponse, ($options->gradingtype==2));
                 $correctresponse = $this->get_next_answerids($this->correctresponse, ($options->gradingtype==2));
                 foreach ($correctresponse as $thisanswerid => $nextanswerid) {
@@ -183,8 +199,8 @@ class qtype_ordering_question extends question_graded_automatically {
                 }
                 break;
 
-            case 3: // RELATIVE_ONE_PREVIOUS_AND_NEXT
-            case 4: // RELATIVE_ALL_PREVIOUS_AND_NEXT
+            case self::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT:
+            case self::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT:
                 $currentresponse = $this->get_previous_and_next_answerids($this->currentresponse, ($options->gradingtype==4));
                 $correctresponse = $this->get_previous_and_next_answerids($this->correctresponse, ($options->gradingtype==4));
                 foreach ($correctresponse as $thisanswerid => $answerids) {
@@ -201,8 +217,9 @@ class qtype_ordering_question extends question_graded_automatically {
                 }
                 break;
 
-            case 5: // LONGEST_ORDERED_SUBSET
-                $subset = $this->get_ordered_subset();
+            case self::GRADING_LONGEST_ORDERED_SUBSET:
+            case self::GRADING_LONGEST_CONTIGUOUS_SUBSET:
+                $subset = $this->get_ordered_subset($options->gradingtype==5);
                 $countcorrect = count($subset);
                 $countanswers = count($this->currentresponse);
                 break;
@@ -349,10 +366,10 @@ class qtype_ordering_question extends question_graded_automatically {
         return $prevnextanswerids;
     }
 
-    public function get_ordered_subset() {
+    public function get_ordered_subset($contiguous) {
         $positions = $this->get_ordered_positions($this->correctresponse,
                                                   $this->currentresponse);
-        $subsets = $this->get_ordered_subsets($positions, count($positions));
+        $subsets = $this->get_ordered_subsets($positions, $contiguous, count($positions));
         $countcorrect = 1; // i.e. ignore single item subsets
         $subsetcorrect = array();
         foreach ($subsets as $subset) {
@@ -373,7 +390,7 @@ class qtype_ordering_question extends question_graded_automatically {
         return $positions;
     }
 
-    public function get_ordered_subsets($positions, $i_max, $i_min=0, $previous=-1) {
+    public function get_ordered_subsets($positions, $contiguous, $i_max, $i_min=0, $previous=-1) {
 
         // $subsets is the collection of all subsets within $positions
         $subsets = array();
@@ -394,18 +411,27 @@ class qtype_ordering_question extends question_graded_automatically {
             if ($current > ($previous + 1)) {
 
                 // fetch all the subsets in the tail of $positions,
-                // and prepend $subset-so-far onto each tail subset
-                $tailsets = $this->get_ordered_subsets($positions, $i_max, $i+1, $previous);
+                $tailsets = $this->get_ordered_subsets($positions, $contiguous, $i_max, $i+1, $previous);
                 foreach ($tailsets as $tailset) {
-                    $subsets[] = array_merge($subset, $tailset);
+                    if ($contiguous) {
+                        // add this tail subset
+                        $subsets[] = $tailset;
+                    } else {
+                        // prepend $subset-so-far to each tail subset
+                        $subsets[] = array_merge($subset, $tailset);
+                    }
                 }
             }
 
-            // add $i to the main subset
-            $subset[] = $i;
+            // decide if we want to add this $i(tem) to the main $subset
+            if ($contiguous==false || $previous < 0 || $current==($previous + 1)) {
 
-            // update the $previous value
-            $previous = $current;
+                // add $i to the main subset
+                $subset[] = $i;
+
+                // update the $previous value
+                $previous = $current;
+            }
         }
         if (count($subset)) {
             // put the main $subset first
@@ -413,4 +439,47 @@ class qtype_ordering_question extends question_graded_automatically {
         }
         return $subsets;
     }
+
+    static public function get_types($types, $type) {
+        if ($type===null) {
+            return $types; // return all $types
+        }
+        if (array_key_exists($type, $types)) {
+            return $types[$type]; // one $type
+        }
+        return $type; // shouldn't happen !!
+    }
+
+    static public function get_select_types($type=null) {
+        $plugin = 'qtype_ordering';
+        $types = array(
+            self::SELECT_ALL        => get_string('selectall',        $plugin),
+            self::SELECT_RANDOM     => get_string('selectrandom',     $plugin),
+            self::SELECT_CONTIGUOUS => get_string('selectcontiguous', $plugin)
+        );
+        return self::get_types($types, $type);
+    }
+
+    static public function get_layout_types($type=null) {
+        $plugin = 'qtype_ordering';
+        $types = array(
+            self::LAYOUT_VERTICAL   => get_string('vertical',   $plugin),
+            self::LAYOUT_HORIZONTAL => get_string('horizontal', $plugin)
+        );
+        return self::get_types($types, $type);
+    }
+
+    static public function get_grading_types($type=null) {
+        $plugin = 'qtype_ordering';
+        $types = array(
+            self::GRADING_ABSOLUTE_POSITION              => get_string('absoluteposition',           $plugin),
+            self::GRADING_RELATIVE_NEXT_EXCLUDE_LAST     => get_string('relativenextexcludelast',    $plugin),
+            self::GRADING_RELATIVE_NEXT_INCLUDE_LAST     => get_string('relativenextincludelast',    $plugin),
+            self::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT => get_string('relativeonepreviousandnext', $plugin),
+            self::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT => get_string('relativeallpreviousandnext', $plugin),
+            self::GRADING_LONGEST_ORDERED_SUBSET         => get_string('longestorderedsubset',       $plugin),
+            self::GRADING_LONGEST_CONTIGUOUS_SUBSET      => get_string('longestcontiguoussubset',    $plugin)
+        );
+        return self::get_types($types, $type);
+    }
 }
diff --git a/question/type/ordering/questiontype.php b/question/type/ordering/questiontype.php
index c4e9a883d25..077e9b95252 100644
--- a/question/type/ordering/questiontype.php
+++ b/question/type/ordering/questiontype.php
@@ -26,9 +26,9 @@
 defined('MOODLE_INTERNAL') || die();
 
 if (class_exists('question_type')) {
-    $register_question_type = false;
+    $register_ordering_questiontype = false;
 } else {
-    $register_question_type = true; // Moodle 2.0
+    $register_ordering_questiontype = true; // Moodle 2.0
     require_once($CFG->dirroot.'/question/type/ordering/legacy/questiontypebase.php');
 }
 
@@ -671,8 +671,9 @@ class qtype_ordering extends question_type {
     }
 }
 
-if ($register_question_type) {
+if ($register_ordering_questiontype) {
     class question_ordering_qtype extends qtype_ordering {
     }
     question_register_questiontype(new question_ordering_qtype());
 }
+unset($register_ordering_questiontype);
diff --git a/question/type/ordering/renderer.php b/question/type/ordering/renderer.php
index a9e76ce4915..eceffb0aeab 100644
--- a/question/type/ordering/renderer.php
+++ b/question/type/ordering/renderer.php
@@ -24,6 +24,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+/** Prevent direct access to this script */
 defined('MOODLE_INTERNAL') || die();
 
 if (! class_exists('qtype_with_combined_feedback_renderer')) { // Moodle 2.0
@@ -64,9 +65,9 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
         $ablock_id          = 'id_ablock_'.$question->id;
 
         switch ($question->options->layouttype) {
-            case 0 : $axis = 'y'; break; // vertical
-            case 1 : $axis = ''; break;  // horizontal
-            default: $axis = '';         // unknown
+            case qtype_ordering_question::LAYOUT_VERTICAL   : $axis = 'y'; break;
+            case qtype_ordering_question::LAYOUT_HORIZONTAL : $axis = '';  break;
+            default: $axis = '';
         }
 
         $result = '';
@@ -178,14 +179,8 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
                 $question = $qa->get_question();
 
                 // fetch grading type
-                switch ($question->options->gradingtype) {
-                    case 0: $gradingtype = get_string('absoluteposition', $plugin); break;
-                    case 1: $gradingtype = get_string('relativenextexcludelast', $plugin); break;
-                    case 2: $gradingtype = get_string('relativenextincludelast', $plugin); break;
-                    case 3: $gradingtype = get_string('relativeonepreviousandnext', $plugin); break;
-                    case 4: $gradingtype = get_string('relativeallpreviousandnext', $plugin); break;
-                    case 5: $gradingtype = get_string('longestorderedsubset', $plugin); break;
-                }
+                $gradingtype = $question->options->gradingtype;
+                $gradingtype = qtype_ordering_question::get_grading_types($gradingtype);
 
                 // format grading type, e.g. Grading type: Relative to next item, excluding last item
                 if ($gradingtype) {
@@ -276,35 +271,32 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
     /////////////////////////////////////
 
     protected function get_response_info($question) {
-        switch ($question->options->gradingtype) {
 
-            case 0: // ABSOLUTE
+        $gradingtype = $question->options->gradingtype;
+        switch ($gradingtype) {
+
+            case qtype_ordering_question::GRADING_ABSOLUTE_POSITION:
                 $this->correctinfo = $question->correctresponse;
                 $this->currentinfo = $question->currentresponse;
                 break;
 
-            case 1: // RELATIVE_NEXT_EXCLUDE_LAST
-                $this->correctinfo = $question->get_next_answerids($question->correctresponse, false);
-                $this->currentinfo = $question->get_next_answerids($question->currentresponse, false);
-                break;
-            case 2: // RELATIVE_NEXT_INCLUDE_LAST
-                $this->correctinfo = $question->get_next_answerids($question->correctresponse, true);
-                $this->currentinfo = $question->get_next_answerids($question->currentresponse, true);
+            case qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST:
+            case qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST:
+                $this->correctinfo = $question->get_next_answerids($question->correctresponse, $gradingtype==2);
+                $this->currentinfo = $question->get_next_answerids($question->currentresponse, $gradingtype==2);
                 break;
 
-            case 3: // RELATIVE_ONE_PREVIOUS_AND_NEXT
-                $this->correctinfo = $question->get_previous_and_next_answerids($question->correctresponse, false);
-                $this->currentinfo = $question->get_previous_and_next_answerids($question->currentresponse, false);
+            case qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT:
+            case qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT:
+                $this->correctinfo = $question->get_previous_and_next_answerids($question->correctresponse, $gradingtype==4);
+                $this->currentinfo = $question->get_previous_and_next_answerids($question->currentresponse, $gradingtype==4);
                 break;
 
-            case 4: // RELATIVE_ALL_PREVIOUS_AND_NEXT
-                $this->correctinfo = $question->get_previous_and_next_answerids($question->correctresponse, true);
-                $this->currentinfo = $question->get_previous_and_next_answerids($question->currentresponse, true);
-                break;
-            case 5: // LONGEST_ORDERED_SUBSET
+            case qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET:
+            case qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET:
                 $this->correctinfo = $question->correctresponse;
                 $this->currentinfo = $question->currentresponse;
-                $subset = $question->get_ordered_subset();
+                $subset = $question->get_ordered_subset($gradingtype==6);
                 foreach ($this->currentinfo as $position => $answerid) {
                     if (array_search($position, $subset)===false) {
                         $this->currentinfo[$position] = 0;
@@ -336,7 +328,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
 
             switch ($question->options->gradingtype) {
 
-                case 0: // ABSOLUTE
+                case qtype_ordering_question::GRADING_ABSOLUTE_POSITION:
                     if (isset($correctinfo[$position])) {
                         if ($correctinfo[$position]==$answerid) {
                             $score = 1;
@@ -345,8 +337,8 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
                     }
                     break;
 
-                case 1; // RELATIVE_NEXT_EXCLUDE_LAST
-                case 2; // RELATIVE_NEXT_INCLUDE_LAST
+                case qtype_ordering_question::GRADING_RELATIVE_NEXT_EXCLUDE_LAST:
+                case qtype_ordering_question::GRADING_RELATIVE_NEXT_INCLUDE_LAST:
                     if (isset($correctinfo[$answerid])) {
                         if (isset($currentinfo[$answerid]) && $currentinfo[$answerid]==$correctinfo[$answerid]) {
                             $score = 1;
@@ -355,8 +347,8 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
                     }
                     break;
 
-                case 3; // RELATIVE_ONE_PREVIOUS_AND_NEXT
-                case 4; // RELATIVE_ALL_PREVIOUS_AND_NEXT
+                case qtype_ordering_question::GRADING_RELATIVE_ONE_PREVIOUS_AND_NEXT:
+                case qtype_ordering_question::GRADING_RELATIVE_ALL_PREVIOUS_AND_NEXT:
                     if (isset($correctinfo[$answerid])) {
                         $maxscore = 0;
                         $prev = $correctinfo[$answerid]->prev;
@@ -370,7 +362,8 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
                     }
                     break;
 
-                case 5: // LONGEST_ORDERED_SUBSET
+                case qtype_ordering_question::GRADING_LONGEST_ORDERED_SUBSET:
+                case qtype_ordering_question::GRADING_LONGEST_CONTIGUOUS_SUBSET:
                     if (isset($correctinfo[$position])) {
                         if (isset($currentinfo[$position])) {
                             $score = $currentinfo[$position];
@@ -383,6 +376,7 @@ class qtype_ordering_renderer extends qtype_with_combined_feedback_renderer {
             if ($maxscore===null) {
                 // an unscored item is either an illegal item
                 // or last item of RELATIVE_NEXT_EXCLUDE_LAST
+                // or an item from an unrecognized grading type
                 $class = 'unscored';
             } else {
                 if ($maxscore==0) {
diff --git a/question/type/ordering/version.php b/question/type/ordering/version.php
index 5587d1e2cc8..fcd34b0f557 100644
--- a/question/type/ordering/version.php
+++ b/question/type/ordering/version.php
@@ -31,5 +31,5 @@ $plugin->cron      = 0;
 $plugin->component = 'qtype_ordering';
 $plugin->maturity  = MATURITY_STABLE;
 $plugin->requires  = 2010112400; // Moodle 2.0
-$plugin->version   = 2016011139;
-$plugin->release   = '2016-01-11 (39)';
+$plugin->version   = 2016012340;
+$plugin->release   = '2016-01-23 (40)';