Skip to content

Commit

Permalink
MDL-48771 quiz edit: delete mulitiple tidy up & Behat tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin Chambers authored and timhunt committed Apr 4, 2017
1 parent 5d803e5 commit f37cffb
Show file tree
Hide file tree
Showing 14 changed files with 746 additions and 334 deletions.
113 changes: 85 additions & 28 deletions mod/quiz/classes/output/edit_renderer.php
Expand Up @@ -59,26 +59,24 @@ public function edit_page(\quiz $quizobj, structure $structure,

// Information at the top.
$output .= $this->quiz_state_warnings($structure);

$output .= html_writer::start_div('mod_quiz-edit-top-controls');
$output .= $this->quiz_information($structure);
$output .= $this->maximum_grade_input($structure, $pageurl);

$output .= html_writer::start_div('mod_quiz-edit-action-buttons btn-group edit-toolbar', ['role' => 'group']);
$output .= $this->repaginate_button($structure, $pageurl);
$output .= $this->bulkaction_button($structure);
$output .= $this->selectmultiple_button($structure);
$output .= html_writer::end_tag('div');

$output .= $this->total_marks($quizobj->get_quiz());

$output .= $this->selectmultiple_controls($structure);
$output .= html_writer::end_tag('div');

// Show the questions organised into sections and pages.
$output .= $this->start_section_list($structure);

// Bulk action button delete and bulk action button cancel.
$output .= html_writer::tag('div', html_writer::empty_tag('input', array('type' => 'button',
'id' => 'bulkactionsdeletecommand', 'value' => get_string('delete', 'moodle'))) . " " .
html_writer::empty_tag('input', array('type' => 'button', 'id' => 'bulkactionscancelcommand',
'value' => get_string('cancel', 'moodle'))), array('class' => 'bulkactioncommand actions'));

// Select all/deselect all questions.
$output .= html_writer::tag('div', html_writer::link('#', get_string('selectall', 'quiz'),
array('id' => 'questionselectall')) . " / " . html_writer::link('#', get_string('selectnone', 'quiz'),
array('id' => 'questiondeselectall')), array('class' => 'bulkactioncommandbuttons'));

foreach ($structure->get_sections() as $section) {
$output .= $this->start_section($structure, $section);
$output .= $this->questions_in_section($structure, $section, $contexts, $pagevars, $pageurl);
Expand Down Expand Up @@ -199,46 +197,105 @@ protected function repaginate_button(structure $structure, \moodle_url $pageurl)

$header = html_writer::tag('span', get_string('repaginatecommand', 'quiz'), array('class' => 'repaginatecommand'));
$form = $this->repaginate_form($structure, $pageurl);
$containeroptions = array(
'class' => 'rpcontainerclass',
'cmid' => $structure->get_cmid(),
'header' => $header,
'form' => $form,
);

$buttonoptions = array(
'type' => 'submit',
'name' => 'repaginate',
'id' => 'repaginatecommand',
'value' => get_string('repaginatecommand', 'quiz'),
'class' => 'btn btn-secondary m-b-1',
'data-header' => $header,
'data-form' => $form,
);
if (!$structure->can_be_repaginated()) {
$buttonoptions['disabled'] = 'disabled';
} else {
$this->page->requires->yui_module('moodle-mod_quiz-repaginate', 'M.mod_quiz.repaginate.init');
}

return html_writer::start_tag('div', $containeroptions) .
html_writer::empty_tag('input', $buttonoptions);
return html_writer::empty_tag('input', $buttonoptions);
}

/**
* Generate the bulk action button
* Generate the bulk action button.
*
* @param structure $structure the structure of the quiz being edited.
* @return string HTML to output.
*/
protected function bulkaction_button(structure $structure) {
protected function selectmultiple_button(structure $structure) {
$buttonoptions = array(
'type' => 'button',
'name' => 'repaginate',
'id' => 'bulkactionscommand',
'value' => get_string('bulkactions', 'quiz'),
'name' => 'selectmultiple',
'id' => 'selectmultiplecommand',
'value' => get_string('selectmultipleitems', 'quiz'),
'class' => 'btn btn-secondary m-b-1'
);
if (!$structure->can_be_repaginated()) {
if (!$structure->can_be_edited()) {
$buttonoptions['disabled'] = 'disabled';
}
return html_writer::empty_tag('input', $buttonoptions) . html_writer::end_tag('div');

return html_writer::tag('button', get_string('selectmultipleitems', 'quiz'), $buttonoptions);
}

/**
* Generate the controls that appear when the bulk action button is pressed.
*
* @param structure $structure the structure of the quiz being edited.
* @return string HTML to output.
*/
protected function selectmultiple_controls(structure $structure) {
$output = '';

// Bulk action button delete and bulk action button cancel.
$buttondeleteoptions = array(
'type' => 'button',
'id' => 'selectmultipledeletecommand',
'value' => get_string('deleteselected', 'mod_quiz'),
'class' => 'btn btn-secondary'
);
$buttoncanceloptions = array(
'type' => 'button',
'id' => 'selectmultiplecancelcommand',
'value' => get_string('cancel', 'moodle'),
'class' => 'btn btn-secondary'
);

$groupoptions = array(
'class' => 'btn-group selectmultiplecommand actions',
'role' => 'group'
);

$output .= html_writer::tag('div',
html_writer::tag('button', get_string('deleteselected', 'mod_quiz'), $buttondeleteoptions) .
" " .
html_writer::tag('button', get_string('cancel', 'moodle'),
$buttoncanceloptions), $groupoptions);

$toolbaroptions = array(
'class' => 'btn-toolbar',
'role' => 'toolbar',
'aria-label' => get_string('selectmultipletoolbar', 'quiz'),
);

// Select all/deselect all questions.
$buttonselectalloptions = array(
'role' => 'button',
'id' => 'questionselectall',
'class' => 'btn btn-link'
);
$buttondeselectalloptions = array(
'role' => 'button',
'id' => 'questiondeselectall',
'class' => 'btn btn-link'
);
$output .= html_writer::tag('div',
html_writer::tag('div',
html_writer::link('#', get_string('selectall', 'quiz'), $buttonselectalloptions) .
html_writer::tag('span', "/", ['class' => 'separator']) .
html_writer::link('#', get_string('selectnone', 'quiz'), $buttondeselectalloptions),
array('class' => 'btn-group selectmultiplecommandbuttons')),
$toolbaroptions);
return $output;
}

/**
Expand Down Expand Up @@ -672,7 +729,7 @@ public function question(structure $structure, $slot, \moodle_url $pageurl) {
$output .= html_writer::start_div('mod-indent-outer');
$output .= html_writer::tag('input', '', array('id' => 'selectquestion-' .
$structure->get_displayed_number_for_slot($slot), 'name' => 'selectquestion[]',
'type' => 'checkbox', 'class' => 'quiz-question-bulk-selector',
'type' => 'checkbox', 'class' => 'select-multiple-checkbox',
'value' => $structure->get_displayed_number_for_slot($slot)));
$output .= $this->question_number($structure->get_displayed_number_for_slot($slot));

Expand Down
52 changes: 30 additions & 22 deletions mod/quiz/edit_rest.php
Expand Up @@ -47,7 +47,7 @@
$newheading = optional_param('newheading', '', PARAM_TEXT);
$shuffle = optional_param('newshuffle', 0, PARAM_INT);
$page = optional_param('page', '', PARAM_INT);
$bulkslots = optional_param('slots', '', PARAM_SEQUENCE);
$ids = optional_param('ids', '', PARAM_SEQUENCE);
$PAGE->set_url('/mod/quiz/edit-rest.php',
array('quizid' => $quizid, 'class' => $class));

Expand All @@ -63,6 +63,9 @@

echo $OUTPUT->header(); // Send headers.

// All these AJAX actions should be logically atomic.
$transaction = $DB->start_delegated_transaction();

// OK, now let's process the parameters and do stuff
// MDL-10221 the DELETE method is not allowed on some web servers,
// so we simulate it with the action URL param.
Expand All @@ -71,6 +74,8 @@
$requestmethod = 'DELETE';
}

$result = null;

switch($requestmethod) {
case 'POST':
case 'GET': // For debugging.
Expand All @@ -81,17 +86,17 @@
switch ($field) {
case 'getsectiontitle':
require_capability('mod/quiz:manage', $modcontext);
echo json_encode(array('instancesection' => $section->heading));
$result = array('instancesection' => $section->heading);
break;
case 'updatesectiontitle':
require_capability('mod/quiz:manage', $modcontext);
$structure->set_section_heading($id, $newheading);
echo json_encode(array('instancesection' => format_string($newheading)));
$result = array('instancesection' => format_string($newheading));
break;
case 'updateshufflequestions':
require_capability('mod/quiz:manage', $modcontext);
$structure->set_section_shuffle($id, $shuffle);
echo json_encode(array('instanceshuffle' => $section->shufflequestions));
$result = array('instanceshuffle' => $section->shufflequestions);
break;
}
break;
Expand All @@ -109,14 +114,13 @@
}
$structure->move_slot($id, $previousid, $page);
quiz_delete_previews($quiz);
echo json_encode(array('visible' => true));
$result = array('visible' => true);
break;

case 'getmaxmark':
require_capability('mod/quiz:manage', $modcontext);
$slot = $DB->get_record('quiz_slots', array('id' => $id), '*', MUST_EXIST);
echo json_encode(array('instancemaxmark' =>
quiz_format_question_grade($quiz, $slot->maxmark)));
$result = array('instancemaxmark' => quiz_format_question_grade($quiz, $slot->maxmark));
break;

case 'updatemaxmark':
Expand All @@ -130,8 +134,8 @@
quiz_update_all_final_grades($quiz);
quiz_update_grades($quiz, 0, true);
}
echo json_encode(array('instancemaxmark' => quiz_format_question_grade($quiz, $maxmark),
'newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades)));
$result = array('instancemaxmark' => quiz_format_question_grade($quiz, $maxmark),
'newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades));
break;

case 'updatepagebreak':
Expand All @@ -142,32 +146,33 @@
$json[$slot->slot] = array('id' => $slot->id, 'slot' => $slot->slot,
'page' => $slot->page);
}
echo json_encode(array('slots' => $json));
$result = array('slots' => $json);
break;

case 'bulkdelete':
case 'deletemultiple':
require_capability('mod/quiz:manage', $modcontext);

$bulkslots = explode(',', $bulkslots);
rsort($bulkslots); // Work backwards, since removing a question renumbers following slots.

foreach ($bulkslots as $slot) {
if (quiz_has_question_use($quiz, $slot)) {
$structure->remove_slot($slot);
$ids = explode(',', $ids);
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)) {
$structure->remove_slot($slot->slot);
}
}
quiz_delete_previews($quiz);
quiz_update_sumgrades($quiz);

echo json_encode(array('deleted' => true));
$result = array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades),
'deleted' => true, 'newnumquestions' => $structure->get_question_count());
break;

case 'updatedependency':
require_capability('mod/quiz:manage', $modcontext);
$slot = $structure->get_slot_by_id($id);
$value = (bool) $value;
$structure->update_question_dependency($slot->id, $value);
echo json_encode(array('requireprevious' => $value));
$result = array('requireprevious' => $value);
break;
}
break;
Expand All @@ -179,7 +184,7 @@
case 'section':
require_capability('mod/quiz:manage', $modcontext);
$structure->remove_section_heading($id);
echo json_encode(array('deleted' => true));
$result = array('deleted' => true);
break;

case 'resource':
Expand All @@ -190,9 +195,12 @@
$structure->remove_slot($slot->slot);
quiz_delete_previews($quiz);
quiz_update_sumgrades($quiz);
echo json_encode(array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades),
'deleted' => true, 'newnumquestions' => $structure->get_question_count()));
$result = array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades),
'deleted' => true, 'newnumquestions' => $structure->get_question_count());
break;
}
break;
}

$transaction->allow_commit();
echo json_encode($result);
3 changes: 2 additions & 1 deletion mod/quiz/lang/en/quiz.php
Expand Up @@ -121,7 +121,6 @@
* The quiz will only start if the student has a JavaScript-enabled web-browser
* The quiz appears in a full screen popup window that covers all the other windows and has no navigation controls
* Students are prevented, as far as is possible, from using facilities like copy and paste';
$string['bulkactions'] = 'Bulk actions';
$string['calculated'] = 'Calculated';
$string['calculatedquestion'] = 'Calculated question not supported at line {$a}. The question will be ignored';
$string['cannotcreatepath'] = 'Path cannot be created ({$a})';
Expand Down Expand Up @@ -817,6 +816,8 @@
$string['selectall'] = 'Select all';
$string['selectcategory'] = 'Select category';
$string['selectedattempts'] = 'Selected attempts...';
$string['selectmultipleitems'] = 'Select multiple items';
$string['selectmultipletoolbar'] = 'Select multiple toolbar';
$string['selectnone'] = 'Deselect all';
$string['selectquestiontype'] = '-- Select question type --';
$string['serveradded'] = 'Server added';
Expand Down

0 comments on commit f37cffb

Please sign in to comment.