From ad8a4d82525dc6b3268ffd63244bcf482fcf7bed Mon Sep 17 00:00:00 2001 From: Shamim Rezaie Date: Fri, 21 Jun 2019 06:06:23 +1000 Subject: [PATCH] MDL-64340 mod_quiz: not display "add random question" when no permission --- mod/quiz/classes/output/edit_renderer.php | 24 ++++++++++--------- mod/quiz/classes/structure.php | 22 +++++++++++++++++ .../tests/behat/editing_add_random.feature | 13 +++++++++- mod/quiz/tests/structure_test.php | 22 +++++++++++++++++ 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/mod/quiz/classes/output/edit_renderer.php b/mod/quiz/classes/output/edit_renderer.php index 59c95e9e7af..34d3fc2166c 100644 --- a/mod/quiz/classes/output/edit_renderer.php +++ b/mod/quiz/classes/output/edit_renderer.php @@ -655,18 +655,20 @@ class edit_renderer extends \plugin_renderer_base { $actions['questionbank'] = new \action_menu_link_secondary($pageurl, $icon, $str->questionbank, $attributes); // Add a random question. - $returnurl = new \moodle_url('/mod/quiz/edit.php', array('cmid' => $structure->get_cmid(), 'data-addonpage' => $page)); - $params = array('returnurl' => $returnurl, 'cmid' => $structure->get_cmid(), 'appendqnumstring' => 'addarandomquestion'); - $url = new \moodle_url('/mod/quiz/addrandom.php', $params); - $icon = new \pix_icon('t/add', $str->addarandomquestion, 'moodle', array('class' => 'iconsmall', 'title' => '')); - $attributes = array('class' => 'cm-edit-action addarandomquestion', 'data-action' => 'addarandomquestion'); - if ($page) { - $title = get_string('addrandomquestiontopage', 'quiz', $page); - } else { - $title = get_string('addrandomquestionatend', 'quiz'); + if ($structure->can_add_random_questions()) { + $returnurl = new \moodle_url('/mod/quiz/edit.php', array('cmid' => $structure->get_cmid(), 'data-addonpage' => $page)); + $params = ['returnurl' => $returnurl, 'cmid' => $structure->get_cmid(), 'appendqnumstring' => 'addarandomquestion']; + $url = new \moodle_url('/mod/quiz/addrandom.php', $params); + $icon = new \pix_icon('t/add', $str->addarandomquestion, 'moodle', array('class' => 'iconsmall', 'title' => '')); + $attributes = array('class' => 'cm-edit-action addarandomquestion', 'data-action' => 'addarandomquestion'); + if ($page) { + $title = get_string('addrandomquestiontopage', 'quiz', $page); + } else { + $title = get_string('addrandomquestionatend', 'quiz'); + } + $attributes = array_merge(array('data-header' => $title, 'data-addonpage' => $page), $attributes); + $actions['addarandomquestion'] = new \action_menu_link_secondary($url, $icon, $str->addarandomquestion, $attributes); } - $attributes = array_merge(array('data-header' => $title, 'data-addonpage' => $page), $attributes); - $actions['addarandomquestion'] = new \action_menu_link_secondary($url, $icon, $str->addarandomquestion, $attributes); // Add a new section to the add_menu if possible. This is always added to the HTML // then hidden with CSS when no needed, so that as things are re-ordered, etc. with diff --git a/mod/quiz/classes/structure.php b/mod/quiz/classes/structure.php index 60ba7d8b247..1c93753559b 100644 --- a/mod/quiz/classes/structure.php +++ b/mod/quiz/classes/structure.php @@ -59,6 +59,9 @@ class structure { /** @var bool caches the results of can_be_edited. */ protected $canbeedited = null; + /** @var bool caches the results of can_add_random_question. */ + protected $canaddrandom = null; + /** @var bool tracks whether tags have been loaded */ protected $hasloadedtags = false; @@ -1093,4 +1096,23 @@ class structure { return isset($this->slottags[$slotid]) ? $this->slottags[$slotid] : []; } + + /** + * Whether the current user can add random questions to the quiz or not. + * It is only possible to add a random question if the user has the moodle/question:useall capability + * on at least one of the contexts related to the one where we are currently editing questions. + * + * @return bool + */ + public function can_add_random_questions() { + if ($this->canaddrandom === null) { + $quizcontext = $this->quizobj->get_context(); + $relatedcontexts = new \question_edit_contexts($quizcontext); + $usablecontexts = $relatedcontexts->having_cap('moodle/question:useall'); + + $this->canaddrandom = !empty($usablecontexts); + } + + return $this->canaddrandom; + } } diff --git a/mod/quiz/tests/behat/editing_add_random.feature b/mod/quiz/tests/behat/editing_add_random.feature index bd5feac6052..2249d113d0e 100644 --- a/mod/quiz/tests/behat/editing_add_random.feature +++ b/mod/quiz/tests/behat/editing_add_random.feature @@ -45,4 +45,15 @@ Feature: Adding random questions to a quiz based on category and tags And I follow "a random question" And I open the autocomplete suggestions list Then "foo" "autocomplete_suggestions" should exist - And "bar" "autocomplete_suggestions" should exist \ No newline at end of file + And "bar" "autocomplete_suggestions" should exist + + Scenario: Teacher without moodle/question:useall should not see the add a random question menu item + Given the following "permission overrides" exist: + | capability | permission | role | contextlevel | reference | + | moodle/question:useall | Prevent | editingteacher | Course | C1 | + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I follow "Quiz 1" + And I navigate to "Edit quiz" in current page administration + When I open the "last" add to quiz menu + Then I should not see "a random question" diff --git a/mod/quiz/tests/structure_test.php b/mod/quiz/tests/structure_test.php index 8bf69cbcb0b..5388b9883a7 100644 --- a/mod/quiz/tests/structure_test.php +++ b/mod/quiz/tests/structure_test.php @@ -1051,4 +1051,26 @@ class mod_quiz_structure_testcase extends advanced_testcase { $this->assertEquals($expected, $actual); } + + /** + * Test for can_add_random_questions. + */ + public function test_can_add_random_questions() { + $this->resetAfterTest(); + + $quiz = $this->create_test_quiz([]); + $course = $quiz->get_course(); + + $generator = $this->getDataGenerator(); + $teacher = $generator->create_and_enrol($course, 'editingteacher'); + $noneditingteacher = $generator->create_and_enrol($course, 'teacher'); + + $this->setUser($teacher); + $structure = \mod_quiz\structure::create_for_quiz($quiz); + $this->assertTrue($structure->can_add_random_questions()); + + $this->setUser($noneditingteacher); + $structure = \mod_quiz\structure::create_for_quiz($quiz); + $this->assertFalse($structure->can_add_random_questions()); + } }