From 358f31672bd3b48488853ad26ad8dc8b4d27ff4c Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Sun, 14 Sep 2014 14:14:11 +0100 Subject: [PATCH] MDL-37998 quiz settings: disableif rules should account for overrides. Some form fields are disabled if only one attempt is allowed. However, there may be an override allowing some students more attempts. We need to account for that possiblity when setting up the disabled if rules. Note the disabledIf is good for usability on this complex form, which is why I don't just want to get rid of them. --- mod/quiz/mod_form.php | 50 +++++++++- .../settings_form_fields_disableif.feature | 92 +++++++++++++++++++ 2 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 mod/quiz/tests/behat/settings_form_fields_disableif.feature diff --git a/mod/quiz/mod_form.php b/mod/quiz/mod_form.php index 912bcae3359..6c8c1f53431 100644 --- a/mod/quiz/mod_form.php +++ b/mod/quiz/mod_form.php @@ -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; + } } diff --git a/mod/quiz/tests/behat/settings_form_fields_disableif.feature b/mod/quiz/tests/behat/settings_form_fields_disableif.feature new file mode 100644 index 00000000000..0e7213ec67d --- /dev/null +++ b/mod/quiz/tests/behat/settings_form_fields_disableif.feature @@ -0,0 +1,92 @@ +@mod @mod_quiz +Feature: Settings form fields disabled if not required + In to create quizzes as simply as possible + As a teacher + I don't need to to use certain form fields. + + Background: + Given the following "users" exist: + | username | firstname | + | teacher | Teach | + | student1 | Student1 | + | student2 | Student2 | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher | C1 | editingteacher | + | student1 | C1 | student | + | student2 | C1 | student | + And I log in as "teacher" + And I follow "Course 1" + And I turn editing mode on + + @javascript + Scenario: Depending on the number of attempts, different form fields are disabled. + When I add a "Quiz" to section "1" + And I expand all fieldsets + And I set the field "Name" to "Test quiz" + And I set the field "Attempts allowed" to "1" + Then the "Grading method" "field" should be disabled + And the "Each attempt builds on the last" "field" should be disabled + And the "id_delay1_enabled" "field" should be disabled + And the "id_delay2_enabled" "field" should be disabled + + When I set the field "Attempts allowed" to "2" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + And the "id_delay1_enabled" "field" should be enabled + And the "id_delay2_enabled" "field" should be disabled + + When I set the field "Attempts allowed" to "3" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + And the "id_delay1_enabled" "field" should be enabled + And the "id_delay2_enabled" "field" should be enabled + + When I set the field "Attempts allowed" to "Unlimited" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + # And the "id_delay1_enabled" "field" should be enabled + # And the "id_delay2_enabled" "field" should be enabled + + When I press "Save and display" + And I navigate to "User overrides" node in "Quiz administration" + And I press "Add user override" + And I set the following fields to these values: + | Override user | Student1 | + | Attempts allowed | 3 | + And I press "Save" + And I navigate to "Edit settings" node in "Quiz administration" + And I set the field "Attempts allowed" to "1" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + And the "id_delay1_enabled" "field" should be enabled + And the "id_delay2_enabled" "field" should be enabled + + When I press "Save and display" + And I navigate to "User overrides" node in "Quiz administration" + And I follow "Edit" + And I set the field "Attempts allowed" to "2" + And I press "Save" + And I navigate to "Edit settings" node in "Quiz administration" + And I set the field "Attempts allowed" to "1" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + And the "id_delay1_enabled" "field" should be enabled + And the "id_delay2_enabled" "field" should be disabled + + When I press "Save and display" + And I navigate to "User overrides" node in "Quiz administration" + And I press "Add user override" + And I set the following fields to these values: + | Override user | Student2 | + | Attempts allowed | Unlimited | + And I press "Save" + And I navigate to "Edit settings" node in "Quiz administration" + And I set the field "Attempts allowed" to "1" + Then the "Grading method" "field" should be enabled + And the "Each attempt builds on the last" "field" should be enabled + And the "id_delay1_enabled" "field" should be enabled + And the "id_delay2_enabled" "field" should be enabled -- 2.43.0