Skip to content

Commit

Permalink
Merge branch 'MDL-76757-401' of https://github.com/danghieu1407/moodle
Browse files Browse the repository at this point in the history
…into MOODLE_401_STABLE
  • Loading branch information
HuongNV13 committed Jul 13, 2023
2 parents e0dc36f + cf0b6e0 commit dcd80cf
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 32 deletions.
12 changes: 9 additions & 3 deletions lang/en/question.php
Expand Up @@ -100,8 +100,13 @@
$string['defaultinfofor'] = 'The default category for questions shared in context \'{$a}\'.';
$string['defaultmarkmustbepositive'] = 'The default mark must be positive.';
$string['deletecoursecategorywithquestions'] = 'There are questions in the question bank associated with this course category. If you proceed, they will be deleted. You may wish to move them first, using the question bank interface.';
$string['deletequestioncheck'] = 'Are you absolutely sure you want to delete \'{$a}\'?';
$string['deletequestionscheck'] = 'Are you absolutely sure you want to delete the following questions?<br /><br />{$a}';
$string['deletequestioncheck'] = 'This will delete the following question and all its versions:<br /><br />{$a}';
$string['deletequestionscheck'] = 'This will delete the following questions and all their versions:<br /><br />{$a}';
$string['deleteselectedquestioncheck'] = 'This will delete selected versions of the following question:<br /><br />{$a}';
$string['deletequestiontitle'] = 'Delete question?';
$string['deletequestiontitle_plural'] = 'Delete questions?';
$string['deleteversiontitle'] = 'Delete selected version?';
$string['deleteversiontitle_plural'] = 'Delete selected versions?';
$string['deletingbehaviour'] = 'Deleting question behaviour \'{$a}\'';
$string['deletingqtype'] = 'Deleting question type \'{$a}\'';
$string['didnotmatchanyanswer'] = '[Did not match any answer]';
Expand Down Expand Up @@ -288,9 +293,10 @@
$string['questioncatsfor'] = 'Question categories for \'{$a}\'';
$string['questiondoesnotexist'] = 'This question does not exist';
$string['questionname'] = 'Question name';
$string['questionnameandquestionversion'] = '{$a->name} v{$a->version}';
$string['questionno'] = 'Question {$a}';
$string['questionsaveerror'] = 'Errors occur during saving question - ({$a})';
$string['questionsinuse'] = '(* Questions marked with an asterisk are used somewhere, for example in a quiz. Therefore, if you proceed, these questions will not really be deleted, they will just be hidden.)';
$string['questionsinuse'] = '* Denotes questions which can\'t be deleted because they are in use. Instead, they will be hidden in the question bank unless you select \'Show old questions\'.';
$string['questionsmovedto'] = 'Questions still in use moved to "{$a}" in the parent course category.';
$string['questionsrescuedfrom'] = 'Questions saved from context {$a}.';
$string['questionsrescuedfrominfo'] = 'These questions (some of which may be hidden) were saved when context {$a} was deleted because they are still used by some quizzes or other activities.';
Expand Down
3 changes: 3 additions & 0 deletions question/bank/deletequestion/classes/delete_action_column.php
Expand Up @@ -96,6 +96,9 @@ protected function get_url_icon_and_label(\stdClass $question): array {
'q' . $question->id => 1,
'sesskey' => sesskey());
$deleteparams = array_merge($deleteparams, $this->returnparams);
if ($this->qbank->base_url()->get_param('deleteall')) {
$deleteparams['deleteall'] = 1;
}
$url = new \moodle_url($this->deletequestionurl, $deleteparams);
return [$url, 't/delete', $this->strdelete];
}
Expand Down
117 changes: 117 additions & 0 deletions question/bank/deletequestion/classes/helper.php
@@ -0,0 +1,117 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace qbank_deletequestion;

/**
* Class helper of qbank_deletequestion.
*
* @package qbank_deletequestion
* @copyright 2023 The Open University
* @since Moodle 4.2
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper {

/**
* Get the confirmation message of delete question.
*
* @param array $questionids List of id questions.
* @param bool $deleteallversions Delete all question version or not.
* @return array List confirmation message.
*/
public static function get_delete_confirmation_message(array $questionids, bool $deleteallversions): array {
global $DB;
$questionnames = '';
$inuse = false;
$hasmutipleversions = false;
$questionversions = [];
$countselectedquestion = count($questionids);
if ($deleteallversions) {
$listofquestions = \question_bank::get_all_versions_of_questions($questionids);
foreach ($listofquestions as $questionbankentry) {
if (count($questionbankentry) > 1 && !$hasmutipleversions) {
$hasmutipleversions = true;
}
// Flip the array to list question by question id. [ qid => qversion ].
$questionversions += array_flip($questionbankentry);
}
// Flatten an array.
$questionids = array_merge(...$listofquestions);
}
[$questionsql, $params] = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED);
$questions = $DB->get_records_select('question', 'id ' . $questionsql, $params,
'name ASC', 'id, name');
foreach ($questions as $question) {
if (questions_in_use([$question->id])) {
$questionnames .= '* ';
$inuse = true;
}
$questionname = format_string($question->name);
if (isset($questionversions[$question->id])) {
$a = new \stdClass();
$a->name = $questionname;
$a->version = $questionversions[$question->id];
$questionnames .= get_string('questionnameandquestionversion',
'question', $a) . '<br />';
} else {
$questionnames .= $questionname . '<br />';
}
}
if ($inuse) {
$questionnames .= '<br />'.get_string('questionsinuse', 'question');
}
$confirmtitle = [
'confirmtitle' => $countselectedquestion > 1 ? get_string('deleteversiontitle_plural',
'question') : get_string('deleteversiontitle', 'question'),
];
$message = get_string('deleteselectedquestioncheck', 'question', $questionnames);
if ($deleteallversions) {
$confirmtitle = [
'confirmtitle' => get_string('deletequestiontitle', 'question'),
];
$message = get_string('deletequestioncheck', 'question', $questionnames);
if ($countselectedquestion > 1) {
$confirmtitle = [
'confirmtitle' => get_string('deletequestiontitle_plural', 'question'),
];
$message = get_string('deletequestionscheck', 'question', $questionnames);
}
}

return [$confirmtitle, $message];
}

/**
* Delete questions has (single/multiple) version.
*
* @param array $questionids List of questionid.
* @param bool $deleteallversions Delete all question version or not.
*/
public static function delete_questions(array $questionids, bool $deleteallversions): void {
if ($deleteallversions) {
// Get all the question id from multidimensional array.
$listofquestions = \question_bank::get_all_versions_of_questions($questionids);
// Flatten an array.
$questionids = array_merge(...$listofquestions);
}
foreach ($questionids as $questionid) {
$questionid = (int) $questionid;
question_require_capability_on($questionid, 'edit');
question_delete_question($questionid);
}
}
}
34 changes: 12 additions & 22 deletions question/bank/deletequestion/delete.php
Expand Up @@ -33,6 +33,7 @@
$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
$cmid = optional_param('cmid', 0, PARAM_INT);
$courseid = optional_param('courseid', 0, PARAM_INT);
$deleteall = optional_param('deleteall', false, PARAM_BOOL);

if ($returnurl) {
$returnurl = new moodle_url($returnurl);
Expand Down Expand Up @@ -79,12 +80,7 @@
$deleteselected = required_param('deleteselected', PARAM_RAW);
if ($confirm == md5($deleteselected)) {
if ($questionlist = explode(',', $deleteselected)) {
// For each question either hide it if it is in use or delete it.
foreach ($questionlist as $questionid) {
$questionid = (int)$questionid;
question_require_capability_on($questionid, 'edit');
question_delete_question($questionid);
}
\qbank_deletequestion\helper::delete_questions($questionlist, $deleteall);
}
redirect($returnurl);
} else {
Expand All @@ -98,35 +94,29 @@
// Make a list of all the questions that are selected.
$rawquestions = $_REQUEST; // This code is called by both POST forms and GET links, so cannot use data_submitted.
$questionlist = ''; // Comma separated list of ids of questions to be deleted.
$questionnames = ''; // String with names of questions separated by <br/> with an asterix in front of those that are in use.
$inuse = false; // Set to true if at least one of the questions is in use.
foreach ($rawquestions as $key => $value) { // Parse input for question ids.
if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
$key = $matches[1];
$questionlist .= $key.',';
question_require_capability_on((int)$key, 'edit');
if (questions_in_use(array($key))) {
$questionnames .= '* ';
$inuse = true;
}
$questionnames .= $DB->get_field('question', 'name', array('id' => $key)) . '<br />';
}
}
if (!$questionlist) { // No questions were selected.
redirect($returnurl);
}
$questionlist = rtrim($questionlist, ',');

// Add an explanation about questions in use.
if ($inuse) {
$questionnames .= '<br />'.get_string('questionsinuse', 'question');
}
$deleteurl = new \moodle_url('/question/bank/deletequestion/delete.php',
array('deleteselected' => $questionlist, 'confirm' => md5($questionlist),
'sesskey' => sesskey(), 'returnurl' => $returnurl, 'cmid' => $cmid, 'courseid' => $courseid));

$deleteurl = new \moodle_url('/question/bank/deletequestion/delete.php', [
'deleteselected' => $questionlist, 'deleteall' => $deleteall, 'confirm' => md5($questionlist),
'sesskey' => sesskey(), 'returnurl' => $returnurl, 'cmid' => $cmid, 'courseid' => $courseid,
]);
$continue = new \single_button($deleteurl, get_string('delete'), 'post');
echo $OUTPUT->confirm(get_string('deletequestionscheck', 'question', $questionnames), $continue, $returnurl);

$questionids = explode(',', $questionlist);
[$displayoptions, $message] = qbank_deletequestion\helper::get_delete_confirmation_message($questionids,
$deleteall);

echo $OUTPUT->confirm($message, $continue, $returnurl, $displayoptions);
}

echo $OUTPUT->footer();
Expand Up @@ -51,7 +51,7 @@ Feature: Use the qbank plugin manager page for deletequestion
And I click on "First question second" "checkbox"
And I click on "With selected" "button"
And I click on question bulk action "deleteselected"
And I click on "Delete" "button" in the "Confirm" "dialogue"
And I click on "Delete" "button" in the "Delete questions?" "dialogue"
Then I should not see "First question"
And I should not see "First question second"

Expand All @@ -68,6 +68,6 @@ Feature: Use the qbank plugin manager page for deletequestion
And I click on "First question" "checkbox"
And I click on "With selected" "button"
And I click on question bulk action "deleteselected"
When I click on "Delete" "button" in the "Confirm" "dialogue"
When I click on "Delete" "button" in the "Delete question?" "dialogue"
Then I should not see "Third question"
And "foo" "autocomplete_selection" should exist

0 comments on commit dcd80cf

Please sign in to comment.