From 94a6d656a62a1a1c397f4dacd31ab7d7249fe1a0 Mon Sep 17 00:00:00 2001
From: tjhunt <tjhunt>
Date: Thu, 28 Aug 2008 01:48:43 +0000
Subject: [PATCH] MDL-8475 - Better handling of blank answer - further changes
 to make it even more robust. Also, make the same changes to the shortanswer
 question type that were already made to the numerical question type.

---
 lang/en_utf8/qtype_shortanswer.php            |   1 +
 lib/moodlelib.php                             |  13 +++
 .../type/numerical/edit_numerical_form.php    |  11 +-
 question/type/numerical/questiontype.php      | 100 +++++++++---------
 .../shortanswer/edit_shortanswer_form.php     |   3 +
 question/type/shortanswer/questiontype.php    |  50 +++++----
 6 files changed, 99 insertions(+), 79 deletions(-)

diff --git a/lang/en_utf8/qtype_shortanswer.php b/lang/en_utf8/qtype_shortanswer.php
index f79f8cd0c9..9a5d85ba38 100644
--- a/lang/en_utf8/qtype_shortanswer.php
+++ b/lang/en_utf8/qtype_shortanswer.php
@@ -2,4 +2,5 @@
 $string['addmoreanswerblanks'] = 'Blanks for {no} More Answers';
 $string['answerno'] = 'Answer $a';
 $string['filloutoneanswer'] = 'You must provide at least one possible answer. Answers left blank will not be used. \'*\' can be used as a wildcard to match any characters. The first matching answer will be used to determine the score and feedback.';
+$string['answermustbegiven'] = 'You must enter an answer if there is a grade or feedback.';
 ?>
\ No newline at end of file
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 4a9fe3a271..5b8b52489e 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -618,6 +618,19 @@ function is_number($value) {
     }
 }
 
+/**
+ * This function is useful for testing whether something you got back from
+ * the HTML editor actually contains anything. Sometimes the HTML editor
+ * appear to be empty, but actually you get back a <br> tag or something.
+ *
+ * @param string $string a string containing HTML.
+ * @return boolean does the string contain any actual content - that is text,
+ * images, objcts, etc.
+ */
+function html_is_blank($string) {
+    return trim(strip_tags($string, '<img><object><applet><input><select><textarea><hr>')) == '';
+}
+
 /**
  * Set a key in global configuration
  *
diff --git a/question/type/numerical/edit_numerical_form.php b/question/type/numerical/edit_numerical_form.php
index 62b7923ac9..ceb3376b49 100644
--- a/question/type/numerical/edit_numerical_form.php
+++ b/question/type/numerical/edit_numerical_form.php
@@ -124,14 +124,9 @@ class question_edit_numerical_form extends question_edit_form {
                 if ($data['fraction'][$key] == 1) {
                     $maxgrade = true;
                 }
-            } else {
-                if ($data['fraction'][$key] !=0 || trim($data['feedback'][$key]) != ''){                
-                    $errors["answer[$key]"] = get_string('answermustbenumberorstar', 'qtype_numerical');
-                    $answercount++;
-                    if (trim($data['feedback'][$key]) != ''){
-                        $errors["feedback[$key]"]=get_string('feedback','quiz').'='.htmlspecialchars(trim($data['feedback'][$key]));
-                    }
-                }
+            } else if ($data['fraction'][$key] != 0 || !html_is_blank($data['feedback'][$key])) {
+                $errors["answer[$key]"] = get_string('answermustbenumberorstar', 'qtype_numerical');
+                $answercount++;
             }
         }
         if ($answercount==0){
diff --git a/question/type/numerical/questiontype.php b/question/type/numerical/questiontype.php
index 68cca25d1c..706a3cf316 100644
--- a/question/type/numerical/questiontype.php
+++ b/question/type/numerical/questiontype.php
@@ -108,59 +108,63 @@ class question_numerical_qtype extends question_shortanswer_qtype {
 
         // Insert all the new answers
         foreach ($question->answer as $key => $dataanswer) {
-            if ( !( trim($dataanswer)=='' && $question->fraction[$key]== 0 && trim($question->feedback[$key])=='')) {
-                $answer = new stdClass;
-                $answer->question = $question->id;
-                if (trim($dataanswer) == '*') {
-                    $answer->answer = '*';
-                } else {
-                    $answer->answer = $this->apply_unit($dataanswer, $units);
-                    if ($answer->answer === false) {
-                        $result->notice = get_string('invalidnumericanswer', 'quiz');
-                    }
-                }
-                $answer->fraction = $question->fraction[$key];
-                $answer->feedback = trim($question->feedback[$key]);
-
-                if ($oldanswer = array_shift($oldanswers)) {  // Existing answer, so reuse it
-                    $answer->id = $oldanswer->id;
-                    if (! $DB->update_record("question_answers", $answer)) {
-                        $result->error = "Could not update quiz answer! (id=$answer->id)";
-                        return $result;
-                    }
-                } else { // This is a completely new answer
-                    if (! $answer->id = $DB->insert_record("question_answers", $answer)) {
-                        $result->error = "Could not insert quiz answer!";
-                        return $result;
-                    }
+            // Check for, and ingore, completely blank answer from the form.
+            if (trim($dataanswer) == '' && $question->fraction[$key] == 0 &&
+                    html_is_blank($question->feedback[$key])) {
+                continue;
+            }
+
+            $answer = new stdClass;
+            $answer->question = $question->id;
+            if (trim($dataanswer) == '*') {
+                $answer->answer = '*';
+            } else {
+                $answer->answer = $this->apply_unit($dataanswer, $units);
+                if ($answer->answer === false) {
+                    $result->notice = get_string('invalidnumericanswer', 'quiz');
                 }
+            }
+            $answer->fraction = $question->fraction[$key];
+            $answer->feedback = trim($question->feedback[$key]);
 
-                // Set up the options object
-                if (!$options = array_shift($oldoptions)) {
-                    $options = new stdClass;
+            if ($oldanswer = array_shift($oldanswers)) {  // Existing answer, so reuse it
+                $answer->id = $oldanswer->id;
+                if (! $DB->update_record("question_answers", $answer)) {
+                    $result->error = "Could not update quiz answer! (id=$answer->id)";
+                    return $result;
                 }
-                $options->question  = $question->id;
-                $options->answer    = $answer->id;
-                if (trim($question->tolerance[$key]) == '') {
-                    $options->tolerance = '';
-                } else {
-                    $options->tolerance = $this->apply_unit($question->tolerance[$key], $units);
-                    if ($options->tolerance === false) {
-                        $result->notice = get_string('invalidnumerictolerance', 'quiz');
-                    }
+            } else { // This is a completely new answer
+                if (! $answer->id = $DB->insert_record("question_answers", $answer)) {
+                    $result->error = "Could not insert quiz answer!";
+                    return $result;
                 }
+            }
 
-                // Save options
-                if (isset($options->id)) { // reusing existing record
-                    if (! $DB->update_record('question_numerical', $options)) {
-                        $result->error = "Could not update quiz numerical options! (id=$options->id)";
-                        return $result;
-                    }
-                } else { // new options
-                    if (! $DB->insert_record('question_numerical', $options)) {
-                        $result->error = "Could not insert quiz numerical options!";
-                        return $result;
-                    }
+            // Set up the options object
+            if (!$options = array_shift($oldoptions)) {
+                $options = new stdClass;
+            }
+            $options->question  = $question->id;
+            $options->answer    = $answer->id;
+            if (trim($question->tolerance[$key]) == '') {
+                $options->tolerance = '';
+            } else {
+                $options->tolerance = $this->apply_unit($question->tolerance[$key], $units);
+                if ($options->tolerance === false) {
+                    $result->notice = get_string('invalidnumerictolerance', 'quiz');
+                }
+            }
+
+            // Save options
+            if (isset($options->id)) { // reusing existing record
+                if (! $DB->update_record('question_numerical', $options)) {
+                    $result->error = "Could not update quiz numerical options! (id=$options->id)";
+                    return $result;
+                }
+            } else { // new options
+                if (! $DB->insert_record('question_numerical', $options)) {
+                    $result->error = "Could not insert quiz numerical options!";
+                    return $result;
                 }
             }
         }
diff --git a/question/type/shortanswer/edit_shortanswer_form.php b/question/type/shortanswer/edit_shortanswer_form.php
index 6df5f11a64..f40ee47863 100644
--- a/question/type/shortanswer/edit_shortanswer_form.php
+++ b/question/type/shortanswer/edit_shortanswer_form.php
@@ -81,6 +81,9 @@ class question_edit_shortanswer_form extends question_edit_form {
                 if ($data['fraction'][$key] == 1) {
                     $maxgrade = true;
                 }
+            } else if ($data['fraction'][$key] != 0 || !html_is_blank($data['feedback'][$key])) {
+                $errors["answer[$key]"] = get_string('answermustbegiven', 'qtype_shortanswer');
+                $answercount++;
             }
         }
         if ($answercount==0){
diff --git a/question/type/shortanswer/questiontype.php b/question/type/shortanswer/questiontype.php
index 3322cd8e30..a01d1da30c 100644
--- a/question/type/shortanswer/questiontype.php
+++ b/question/type/shortanswer/questiontype.php
@@ -51,32 +51,36 @@ class question_shortanswer_qtype extends default_questiontype {
 
         // Insert all the new answers
         foreach ($question->answer as $key => $dataanswer) {
-            if ($dataanswer != "") {
-                if ($oldanswer = array_shift($oldanswers)) {  // Existing answer, so reuse it
-                    $answer = $oldanswer;
-                    $answer->answer   = trim($dataanswer);
-                    $answer->fraction = $question->fraction[$key];
-                    $answer->feedback = $question->feedback[$key];
-                    if (!$DB->update_record("question_answers", $answer)) {
-                        $result->error = "Could not update quiz answer! (id=$answer->id)";
-                        return $result;
-                    }
-                } else {    // This is a completely new answer
-                    $answer = new stdClass;
-                    $answer->answer   = trim($dataanswer);
-                    $answer->question = $question->id;
-                    $answer->fraction = $question->fraction[$key];
-                    $answer->feedback = $question->feedback[$key];
-                    if (!$answer->id = $DB->insert_record("question_answers", $answer)) {
-                        $result->error = "Could not insert quiz answer!";
-                        return $result;
-                    }
+            // Check for, and ingore, completely blank answer from the form.
+            if (trim($dataanswer) == '' && $question->fraction[$key] == 0 &&
+                    html_is_blank($question->feedback[$key])) {
+                continue;
+            }
+
+            if ($oldanswer = array_shift($oldanswers)) {  // Existing answer, so reuse it
+                $answer = $oldanswer;
+                $answer->answer   = trim($dataanswer);
+                $answer->fraction = $question->fraction[$key];
+                $answer->feedback = $question->feedback[$key];
+                if (!$DB->update_record("question_answers", $answer)) {
+                    $result->error = "Could not update quiz answer! (id=$answer->id)";
+                    return $result;
                 }
-                $answers[] = $answer->id;
-                if ($question->fraction[$key] > $maxfraction) {
-                    $maxfraction = $question->fraction[$key];
+            } else {    // This is a completely new answer
+                $answer = new stdClass;
+                $answer->answer   = trim($dataanswer);
+                $answer->question = $question->id;
+                $answer->fraction = $question->fraction[$key];
+                $answer->feedback = $question->feedback[$key];
+                if (!$answer->id = $DB->insert_record("question_answers", $answer)) {
+                    $result->error = "Could not insert quiz answer!";
+                    return $result;
                 }
             }
+            $answers[] = $answer->id;
+            if ($question->fraction[$key] > $maxfraction) {
+                $maxfraction = $question->fraction[$key];
+            }
         }
 
         if ($options = $DB->get_record("question_shortanswer", array("question" => $question->id))) {
-- 
2.39.5