Merge branch 'MDL-75642-master' of https://github.com/BruceGoodGuy/moodle

This commit is contained in:
Shamim Rezaie
2022-10-13 16:28:10 +11:00
8 changed files with 132 additions and 3 deletions
+1 -1
View File
@@ -271,7 +271,7 @@ class quiz {
/**
* Get the quiz context.
*
* @return context the module context for this quiz.
* @return context_module the module context for this quiz.
*/
public function get_context() {
return $this->context;
+1 -1
View File
@@ -823,7 +823,7 @@ class edit_renderer extends \plugin_renderer_base {
$structure->get_question_in_slot($slot),
null, null, $qtype);
}
if ($structure->can_be_edited()) {
if ($structure->can_be_edited() && $structure->has_use_capability($slot)) {
$questionicons .= $this->question_remove_icon($structure, $slot, $pageurl);
}
$questionicons .= $this->marked_out_of_field($structure, $slot);
+19
View File
@@ -244,6 +244,25 @@ class structure {
return $this->get_question_in_slot($slotnumber)->length != 0;
}
/**
* Does the current user have '...use' capability over the question(s) in a given slot?
*
*
* @param int $slotnumber the index of the slot in question.
* @return bool true if they have the required capability.
*/
public function has_use_capability(int $slotnumber): bool {
$slot = $this->slotsinorder[$slotnumber];
if (is_numeric($slot->questionid)) {
// Non-random question.
return question_has_capability_on($this->get_question_by_id($slot->questionid), 'use');
} else {
// Random question.
$context = \context::instance_by_id($slot->contextid);
return has_capability('moodle/question:useall', $context);
}
}
/**
* Get the course id that the quiz belongs to.
* @return int the course.id for the quiz.
+8 -1
View File
@@ -156,7 +156,7 @@ switch($requestmethod) {
foreach ($ids as $id) {
$slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id),
'*', MUST_EXIST);
if (quiz_has_question_use($quiz, $slot->slot)) {
if ($structure->has_use_capability($slot->slot)) {
$structure->remove_slot($slot->slot);
}
}
@@ -192,6 +192,13 @@ switch($requestmethod) {
if (!$slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id))) {
throw new moodle_exception('AJAX commands.php: Bad slot ID '.$id);
}
if (!$structure->has_use_capability($slot->slot)) {
$slotdetail = $structure->get_slot_by_id($slot->id);
$context = context::instance_by_id($slotdetail->contextid);
throw new required_capability_exception($context,
'moodle/question:useall', 'nopermissions', '');
}
$structure->remove_slot($slot->slot);
quiz_delete_previews($quiz);
quiz_update_sumgrades($quiz);
+5
View File
@@ -2266,6 +2266,9 @@ function quiz_require_question_use($questionid) {
/**
* Verify that the question exists, and the user has permission to use it.
*
* @deprecated in 4.1 use mod_quiz\structure::has_use_capability(...) instead.
*
* @param object $quiz the quiz settings.
* @param int $slot which question in the quiz to test.
* @return bool whether the user can use this question.
@@ -2273,6 +2276,8 @@ function quiz_require_question_use($questionid) {
function quiz_has_question_use($quiz, $slot) {
global $DB;
debugging('Deprecated. Please use mod_quiz\structure::has_use_capability instead.');
$sql = 'SELECT q.*
FROM {quiz_slots} slot
JOIN {question_references} qre ON qre.itemid = slot.id
@@ -236,3 +236,61 @@ Feature: Edit quiz page - remove multiple questions
And I click on "Delete selected" "button"
Then I should see "Cannot remove questions"
@javascript
Scenario: Delete multiple random questions from sections.
Given the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | Question A | First question |
| Test questions | truefalse | Question B | Second question |
| Test questions | truefalse | Question C | Third question |
| Test questions | truefalse | Question D | Fourth question |
| Test questions | truefalse | Question E | Fifth question |
| Test questions | truefalse | Question F | Sixth question |
And I am on the "Quiz 1" "mod_quiz > Edit" page
When I open the "last" add to quiz menu
And I follow "a random question"
And I set the field "Number of random questions" to "3"
And I press "Add random question"
And I click on "Select multiple items" "button"
And I click on "selectquestion-1" "checkbox"
And I click on "selectquestion-2" "checkbox"
And I click on "Delete selected" "button"
And I click on "Yes" "button" in the "Confirm" "dialogue"
# To make sure question is deleted completely.
And I reload the page
Then I should see "Random (Test questions)" on quiz page "1"
And I should not see "Random (Test questions)" on quiz page "2"
And I should not see "Random (Test questions)" on quiz page "3"
And I should see "Total of marks: 1.00"
And I should see "Questions: 1"
@javascript
Scenario: Delete all random questions by checking select all.
Given the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | Question A | First question |
| Test questions | truefalse | Question B | Second question |
| Test questions | truefalse | Question C | Third question |
| Test questions | truefalse | Question D | Fourth question |
| Test questions | truefalse | Question E | Fifth question |
| Test questions | truefalse | Question F | Sixth question |
And I am on the "Quiz 1" "mod_quiz > Edit" page
# Delete all questions in page. Page contains multiple questions.
When I open the "last" add to quiz menu
And I follow "a random question"
And I set the field "Number of random questions" to "3"
And I press "Add random question"
And I click on "Select multiple items" "button"
And I press "Select all"
And I click on "Delete selected" "button"
And I click on "Yes" "button" in the "Confirm" "dialogue"
# To make sure question is deleted completely.
And I reload the page
Then I should not see "Random (Test questions)" on quiz page "1"
And I should not see "Random (Test questions)" on quiz page "2"
And I should not see "Random (Test questions)" on quiz page "3"
And I should see "Total of marks: 0.00"
And I should see "Questions: 0"
+35
View File
@@ -958,4 +958,39 @@ class structure_test extends \advanced_testcase {
$this->assertFalse($versiondata[2]->selected);
$this->assertFalse($versiondata[3]->selected);
}
/**
* Test the current user have '...use' capability over the question(s) in a given slot.
*
* @covers ::has_use_capability
*/
public function test_has_use_capability() {
$this->resetAfterTest();
// Create a quiz with question.
$quizobj = $this->create_test_quiz([]);
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
$cat = $questiongenerator->create_question_category(['contextid' => $quizobj->get_context()->id]);
$q = $questiongenerator->create_question('essay', null,
['category' => $cat->id, 'name' => 'This is essay question']);
quiz_add_quiz_question($q->id, $quizobj->get_quiz());
// Create the quiz object.
$structure = structure::create_for_quiz($quizobj);
$slots = $structure->get_slots();
// Get slot.
$slotid = array_pop($slots)->slot;
$course = $quizobj->get_course();
$generator = $this->getDataGenerator();
$teacher = $generator->create_and_enrol($course, 'editingteacher');
$student = $generator->create_and_enrol($course);
$this->setUser($teacher);
$this->assertTrue($structure->has_use_capability($slotid));
$this->setUser($student);
$this->assertFalse($structure->has_use_capability($slotid));
}
}
+5
View File
@@ -1,5 +1,10 @@
This files describes API changes in the quiz code.
=== 4.1 ===
* quiz_has_question_use is now deprecated. Use mod_quiz\structure::has_use_capability istead.
=== 4.0.3, 4.1 ===
* If a quiz is sequential the external functions mod_quiz_external::get_attempt_data, mod_quiz_external::get_attempt_summary will not return any data