Skip to content

Commit

Permalink
Merge branch 'MDL-32240' of git://github.com/timhunt/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
stronk7 committed Apr 3, 2012
2 parents eeb3295 + 76cf77e commit 959a709
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 40 deletions.
26 changes: 23 additions & 3 deletions lib/questionlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1047,10 +1047,13 @@ function question_make_default_categories($contexts) {
} else {
$category = question_get_default_category($context->id);
}
if ($preferredlevels[$context->contextlevel] > $preferredness && has_any_capability(
array('moodle/question:usemine', 'moodle/question:useall'), $context)) {
$thispreferredness = $preferredlevels[$context->contextlevel];
if (has_any_capability(array('moodle/question:usemine', 'moodle/question:useall'), $context)) {
$thispreferredness += 10;
}
if ($thispreferredness > $preferredness) {
$toreturn = $category;
$preferredness = $preferredlevels[$context->contextlevel];
$preferredness = $thispreferredness;
}
}

Expand Down Expand Up @@ -1575,6 +1578,23 @@ public function having_one_edit_tab_cap($tabname) {
return $this->having_one_cap(self::$caps[$tabname]);
}

/**
* @return those contexts where a user can add a question and then use it.
*/
public function having_add_and_use() {
$contextswithcap = array();
foreach ($this->allcontexts as $context) {
if (!has_capability('moodle/question:add', $context)) {
continue;
}
if (!has_any_capability(array('moodle/question:useall', 'moodle/question:usemine'), $context)) {
continue;
}
$contextswithcap[] = $context;
}
return $contextswithcap;
}

/**
* Has at least one parent context got the cap $cap?
*
Expand Down
6 changes: 5 additions & 1 deletion mod/quiz/addrandom.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@
if (!$course = $DB->get_record('course', array('id' => $quiz->course))) {
print_error('invalidcourseid');
}
//you need mod/quiz:manage in addition to question capabilities to access this page.
// You need mod/quiz:manage in addition to question capabilities to access this page.
// You also need the moodle/question:useall capability somewhere.
require_capability('mod/quiz:manage', $contexts->lowest());
if (!$contexts->having_cap('moodle/question:useall')) {
print_error('nopermissions', '', '', 'use');
}

$PAGE->set_url($thispageurl);

Expand Down
5 changes: 3 additions & 2 deletions mod/quiz/addrandomform.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ protected function definition() {
$mform =& $this->_form;

$contexts = $this->_customdata;
$usablecontexts = $contexts->having_cap('moodle/question:useall');

//--------------------------------------------------------------------------------
$mform->addElement('header', 'categoryheader',
get_string('randomfromexistingcategory', 'quiz'));

$mform->addElement('questioncategory', 'category', get_string('category'),
array('contexts' => $contexts->all(), 'top' => false));
array('contexts' => $usablecontexts, 'top' => false));

$mform->addElement('checkbox', 'includesubcategories', '', get_string('recurse', 'quiz'));

Expand All @@ -62,7 +63,7 @@ protected function definition() {
$mform->setType('name', PARAM_MULTILANG);

$mform->addElement('questioncategory', 'parent', get_string('parentcategory', 'question'),
array('contexts' => $contexts->all(), 'top' => true));
array('contexts' => $usablecontexts, 'top' => true));
$mform->addHelpButton('parent', 'parentcategory', 'question');

$mform->addElement('submit', 'newcategory',
Expand Down
35 changes: 23 additions & 12 deletions mod/quiz/edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@
*/
function module_specific_buttons($cmid, $cmoptions) {
global $OUTPUT;
$params = array(
'type' => 'submit',
'name' => 'add',
'value' => $OUTPUT->larrow() . ' ' . get_string('addtoquiz', 'quiz'),
);
if ($cmoptions->hasattempts) {
$disabled = 'disabled="disabled" ';
} else {
$disabled = '';
$params['disabled'] = 'disabled';
}
$out = '<input type="submit" name="add" value="' . $OUTPUT->larrow() . ' ' .
get_string('addtoquiz', 'quiz') . '" ' . $disabled . "/>\n";
return $out;
return html_writer::empty_tag('input', $params);
}

/**
Expand Down Expand Up @@ -137,7 +138,9 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo
$quiz_reordertool = get_user_preferences('quiz_reordertab', 0);
}

//will be set further down in the code
$canaddrandom = $contexts->have_cap('moodle/question:useall');
$canaddquestion = (bool) $contexts->having_add_and_use();

$quizhasattempts = quiz_has_attempts($quiz->id);

$PAGE->set_url($thispageurl);
Expand Down Expand Up @@ -211,6 +214,7 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo

if (($addquestion = optional_param('addquestion', 0, PARAM_INT)) && confirm_sesskey()) {
// Add a single question to the current quiz
quiz_require_question_use($addquestion);
$addonpage = optional_param('addonpage', 0, PARAM_INT);
quiz_add_quiz_question($addquestion, $quiz, $addonpage);
quiz_delete_previews($quiz);
Expand All @@ -225,6 +229,7 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo
foreach ($rawdata as $key => $value) { // Parse input for question ids
if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
$key = $matches[1];
quiz_require_question_use($key);
quiz_add_quiz_question($key, $quiz);
}
}
Expand Down Expand Up @@ -273,7 +278,11 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo
}

$remove = optional_param('remove', false, PARAM_INT);
if (($remove = optional_param('remove', false, PARAM_INT)) && confirm_sesskey()) {
if ($remove && confirm_sesskey()) {
// Remove a question from the quiz.
// We require the user to have the 'use' capability on the question,
// so that then can add it back if they remove the wrong one by mistake.
quiz_require_question_use($remove);
quiz_remove_question($quiz, $remove);
quiz_delete_previews($quiz);
quiz_update_sumgrades($quiz);
Expand All @@ -283,7 +292,9 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo
if (optional_param('quizdeleteselected', false, PARAM_BOOL) &&
!empty($selectedquestionids) && confirm_sesskey()) {
foreach ($selectedquestionids as $questionid) {
quiz_remove_question($quiz, $questionid);
if (quiz_has_question_use($questionid)) {
quiz_remove_question($quiz, $questionid);
}
}
quiz_delete_previews($quiz);
quiz_update_sumgrades($quiz);
Expand Down Expand Up @@ -548,14 +559,14 @@ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmo
echo '<div class="editq">';
}

quiz_print_question_list($quiz, $thispageurl, true,
$quiz_reordertool, $quiz_qbanktool, $quizhasattempts, $defaultcategoryobj);
quiz_print_question_list($quiz, $thispageurl, true, $quiz_reordertool, $quiz_qbanktool,
$quizhasattempts, $defaultcategoryobj, $canaddquestion, $canaddrandom);
echo '</div>';

// Close <div class="quizcontents">:
echo '</div>';

if (!$quiz_reordertool) {
if (!$quiz_reordertool && $canaddrandom) {
$randomform = new quiz_add_random_form(new moodle_url('/mod/quiz/addrandom.php'), $contexts);
$randomform->set_data(array(
'category' => $pagevars['cat'],
Expand Down
79 changes: 58 additions & 21 deletions mod/quiz/editlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@

define('NUM_QS_TO_SHOW_IN_RANDOM', 3);

/**
* Verify that the question exists, and the user has permission to use it.
* Does not return. Throws an exception if the question cannot be used.
* @param int $questionid The id of the question.
*/
function quiz_require_question_use($questionid) {
global $DB;
$question = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST);
question_require_capability_on($question, 'use');
}

/**
* Verify that the question exists, and the user has permission to use it.
* @param int $questionid The id of the question.
* @return bool whether the user can use this question.
*/
function quiz_has_question_use($questionid) {
global $DB;
$question = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST);
return question_has_capability_on($question, 'use');
}

/**
* Remove a question from a quiz
* @param object $quiz the quiz object.
Expand Down Expand Up @@ -333,19 +355,21 @@ function quiz_move_question_down($layout, $questionid) {
* Prints a list of quiz questions for the edit.php main view for edit
* ($reordertool = false) and order and paging ($reordertool = true) tabs
*
* @return int sum of maximum grades
* @param object $quiz This is not the standard quiz object used elsewhere but
* it contains the quiz layout in $quiz->questions and the grades in
* $quiz->grades
* @param object $pageurl The url of the current page with the parameters required
* @param moodle_url $pageurl The url of the current page with the parameters required
* for links returning to the current page, as a moodle_url object
* @param bool $allowdelete Indicates whether the delete icons should be displayed
* @param bool $reordertool Indicates whether the reorder tool should be displayed
* @param bool $quiz_qbanktool Indicates whether the question bank should be displayed
* @param bool $hasattempts Indicates whether the quiz has attempts
* @param object $defaultcategoryobj
* @param bool $canaddquestion is the user able to add and use questions anywere?
* @param bool $canaddrandom is the user able to add random questions anywere?
*/
function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
$quiz_qbanktool, $hasattempts, $defaultcategoryobj) {
$quiz_qbanktool, $hasattempts, $defaultcategoryobj, $canaddquestion, $canaddrandom) {
global $CFG, $DB, $OUTPUT;
$strorder = get_string('order');
$strquestionname = get_string('questionname', 'quiz');
Expand Down Expand Up @@ -667,7 +691,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
if (!$reordertool && !($quiz->shufflequestions &&
$count < $questiontotalcount - 1)) {
quiz_print_pagecontrols($quiz, $pageurl, $pagecount,
$hasattempts, $defaultcategoryobj);
$hasattempts, $defaultcategoryobj, $canaddquestion, $canaddrandom);
} else if ($count < $questiontotalcount - 1) {
//do not include the last page break for reordering
//to avoid creating a new extra page in the end
Expand Down Expand Up @@ -703,12 +727,19 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool,
* Print all the controls for adding questions directly into the
* specific page in the edit tab of edit.php
*
* @param unknown_type $quiz
* @param unknown_type $pageurl
* @param unknown_type $page
* @param unknown_type $hasattempts
* @param object $quiz This is not the standard quiz object used elsewhere but
* it contains the quiz layout in $quiz->questions and the grades in
* $quiz->grades
* @param moodle_url $pageurl The url of the current page with the parameters required
* for links returning to the current page, as a moodle_url object
* @param int $page the current page number.
* @param bool $hasattempts Indicates whether the quiz has attempts
* @param object $defaultcategoryobj
* @param bool $canaddquestion is the user able to add and use questions anywere?
* @param bool $canaddrandom is the user able to add random questions anywere?
*/
function quiz_print_pagecontrols($quiz, $pageurl, $page, $hasattempts, $defaultcategoryobj) {
function quiz_print_pagecontrols($quiz, $pageurl, $page, $hasattempts,
$defaultcategoryobj, $canaddquestion, $canaddrandom) {
global $CFG, $OUTPUT;
static $randombuttoncount = 0;
$randombuttoncount++;
Expand All @@ -724,22 +755,25 @@ function quiz_print_pagecontrols($quiz, $pageurl, $page, $hasattempts, $defaultc
$defaultcategoryid = $defaultcategoryobj->id;
}

// Create the url the question page will return to
$returnurladdtoquiz = new moodle_url($pageurl, array('addonpage' => $page));

// Print a button linking to the choose question type page.
$returnurladdtoquiz = $returnurladdtoquiz->out_as_local_url(false);
$newquestionparams = array('returnurl' => $returnurladdtoquiz,
'cmid' => $quiz->cmid, 'appendqnumstring' => 'addquestion');
create_new_question_button($defaultcategoryid, $newquestionparams,
get_string('addaquestion', 'quiz'),
get_string('createquestionandadd', 'quiz'), $hasattempts);
if ($canaddquestion) {
// Create the url the question page will return to
$returnurladdtoquiz = new moodle_url($pageurl, array('addonpage' => $page));

// Print a button linking to the choose question type page.
$returnurladdtoquiz = $returnurladdtoquiz->out_as_local_url(false);
$newquestionparams = array('returnurl' => $returnurladdtoquiz,
'cmid' => $quiz->cmid, 'appendqnumstring' => 'addquestion');
create_new_question_button($defaultcategoryid, $newquestionparams,
get_string('addaquestion', 'quiz'),
get_string('createquestionandadd', 'quiz'), $hasattempts);
}

if ($hasattempts) {
$disabled = 'disabled="disabled"';
} else {
$disabled = '';
}
if ($canaddrandom) {
?>
<div class="singlebutton">
<form class="randomquestionform" action="<?php echo $CFG->wwwroot;
Expand All @@ -760,8 +794,8 @@ function quiz_print_pagecontrols($quiz, $pageurl, $page, $hasattempts, $defaultc
</div>
</form>
</div>
<?php echo $OUTPUT->help_icon('addarandomquestion', 'quiz'); ?>
<?php
<?php echo $OUTPUT->help_icon('addarandomquestion', 'quiz');
}
echo "\n</div>";
}

Expand Down Expand Up @@ -1021,6 +1055,9 @@ public function get_name() {
}

protected function display_content($question, $rowclasses) {
if (!question_has_capability_on($question, 'use')) {
return;
}
// for RTL languages: switch right and left arrows
if (right_to_left()) {
$movearrow = 't/removeright';
Expand Down
1 change: 1 addition & 0 deletions question/editlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ protected function display_content($question, $rowclasses) {
echo '<input title="' . $this->strselect . '" type="checkbox" name="q' .
$question->id . '" id="checkq' . $question->id . '" value="1"/>';
if ($this->firstrow) {
$PAGE->requires->js('/question/qbank.js');
$PAGE->requires->js_function_call('question_bank.init_checkbox_column', array(get_string('selectall'),
get_string('deselectall'), 'checkq' . $question->id));
$this->firstrow = false;
Expand Down
1 change: 1 addition & 0 deletions question/question.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
$formeditable = true;
require_capability('moodle/question:add', $categorycontext);
}
$question->formoptions->mustbeusable = (bool) $appendqnumstring;

// Validate the question type.
$PAGE->set_pagetype('question-type-' . $question->qtype);
Expand Down
8 changes: 7 additions & 1 deletion question/type/edit_question_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,15 @@ protected function definition() {
$mform->addElement('header', 'generalheader', get_string("general", 'form'));

if (!isset($this->question->id)) {
if (!empty($this->question->formoptions->mustbeusable)) {
$contexts = $this->contexts->having_add_and_use();
} else {
$contexts = $this->contexts->having_cap('moodle/question:add');
}

// Adding question
$mform->addElement('questioncategory', 'category', get_string('category', 'question'),
array('contexts' => $this->contexts->having_cap('moodle/question:add')));
array('contexts' => $contexts));
} else if (!($this->question->formoptions->canmove ||
$this->question->formoptions->cansaveasnew)) {
// Editing question with no permission to move from category.
Expand Down

0 comments on commit 959a709

Please sign in to comment.