MDL-37998 quiz settings: disableif rules should account for overrides.
[moodle.git] / mod / quiz / mod_form.php
index 912bcae..6c8c1f5 100644 (file)
@@ -42,6 +42,9 @@ class mod_quiz_mod_form extends moodleform_mod {
     protected $_feedbacks;
     protected static $reviewfields = array(); // Initialised in the constructor.
 
+    /** @var int the max number of attempts allowed in any user or group override on this quiz. */
+    protected $maxattemptsanyoverride = null;
+
     public function __construct($current, $section, $cm, $course) {
         self::$reviewfields = array(
             'attempt'          => array('theattempt', 'quiz'),
@@ -136,7 +139,9 @@ class mod_quiz_mod_form extends moodleform_mod {
         $mform->addHelpButton('grademethod', 'grademethod', 'quiz');
         $mform->setAdvanced('grademethod', $quizconfig->grademethod_adv);
         $mform->setDefault('grademethod', $quizconfig->grademethod);
-        $mform->disabledIf('grademethod', 'attempts', 'eq', 1);
+        if ($this->get_max_attempts_for_any_override() < 2) {
+            $mform->disabledIf('grademethod', 'attempts', 'eq', 1);
+        }
 
         // -------------------------------------------------------------------------------
         $mform->addElement('header', 'layouthdr', get_string('layout', 'quiz'));
@@ -219,7 +224,9 @@ class mod_quiz_mod_form extends moodleform_mod {
         $mform->addHelpButton('attemptonlast', 'eachattemptbuildsonthelast', 'quiz');
         $mform->setAdvanced('attemptonlast', $quizconfig->attemptonlast_adv);
         $mform->setDefault('attemptonlast', $quizconfig->attemptonlast);
-        $mform->disabledIf('attemptonlast', 'attempts', 'eq', 1);
+        if ($this->get_max_attempts_for_any_override() < 2) {
+            $mform->disabledIf('attemptonlast', 'attempts', 'eq', 1);
+        }
 
         // -------------------------------------------------------------------------------
         $mform->addElement('header', 'reviewoptionshdr',
@@ -309,15 +316,19 @@ class mod_quiz_mod_form extends moodleform_mod {
         $mform->addHelpButton('delay1', 'delay1st2nd', 'quiz');
         $mform->setAdvanced('delay1', $quizconfig->delay1_adv);
         $mform->setDefault('delay1', $quizconfig->delay1);
-        $mform->disabledIf('delay1', 'attempts', 'eq', 1);
+        if ($this->get_max_attempts_for_any_override() < 2) {
+            $mform->disabledIf('delay1', 'attempts', 'eq', 1);
+        }
 
         $mform->addElement('duration', 'delay2', get_string('delaylater', 'quiz'),
                 array('optional' => true));
         $mform->addHelpButton('delay2', 'delaylater', 'quiz');
         $mform->setAdvanced('delay2', $quizconfig->delay2_adv);
         $mform->setDefault('delay2', $quizconfig->delay2);
-        $mform->disabledIf('delay2', 'attempts', 'eq', 1);
-        $mform->disabledIf('delay2', 'attempts', 'eq', 2);
+        if ($this->get_max_attempts_for_any_override() < 3) {
+            $mform->disabledIf('delay2', 'attempts', 'eq', 1);
+            $mform->disabledIf('delay2', 'attempts', 'eq', 2);
+        }
 
         // Browser security choices.
         $mform->addElement('select', 'browsersecurity', get_string('browsersecurity', 'quiz'),
@@ -618,4 +629,33 @@ class mod_quiz_mod_form extends moodleform_mod {
     public function completion_rule_enabled($data) {
         return !empty($data['completionattemptsexhausted']) || !empty($data['completionpass']);
     }
+
+    /**
+     * Get the maximum number of attempts that anyone might have due to a user
+     * or group override. Used to decide whether disabledIf rules should be applied.
+     * @return int the number of attempts allowed. For the purpose of this method,
+     * unlimited is returned as 1000, not 0.
+     */
+    public function get_max_attempts_for_any_override() {
+        global $DB;
+
+        if (empty($this->_instance)) {
+            // Quiz not created yet, so no overrides.
+            return 1;
+        }
+
+        if ($this->maxattemptsanyoverride === null) {
+            $this->maxattemptsanyoverride = $DB->get_field_sql("
+                    SELECT MAX(CASE WHEN attempts = 0 THEN 1000 ELSE attempts END)
+                      FROM {quiz_overrides}
+                     WHERE quiz = ?",
+                    array($this->_instance));
+            if ($this->maxattemptsanyoverride < 1) {
+                // This happens when no override alters the number of attempts.
+                $this->maxattemptsanyoverride = 1;
+            }
+        }
+
+        return $this->maxattemptsanyoverride;
+    }
 }