first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,11 @@
define("qbank_deletequestion/datafilter/filtertypes/hidden",["exports","core/datafilter/filtertypes/binary"],(function(_exports,_binary){var obj;
/**
* Filter managing hidden questions.
*
* @module qbank_deletequestion/datafilter/filtertypes/hidden
* @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @copyright 2022 Catalyst IT Australia Pty Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_binary=(obj=_binary)&&obj.__esModule?obj:{default:obj};class _default extends _binary.default{}return _exports.default=_default,_exports.default}));
//# sourceMappingURL=hidden.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"hidden.min.js","sources":["../../../src/datafilter/filtertypes/hidden.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Filter managing hidden questions.\n *\n * @module qbank_deletequestion/datafilter/filtertypes/hidden\n * @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>\n * @copyright 2022 Catalyst IT Australia Pty Ltd\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Binary from 'core/datafilter/filtertypes/binary';\n\nexport default class extends Binary {\n}\n"],"names":["Binary"],"mappings":";;;;;;;;oKA0B6BA"}
@@ -0,0 +1,28 @@
// 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/>.
/**
* Filter managing hidden questions.
*
* @module qbank_deletequestion/datafilter/filtertypes/hidden
* @author 2022 Ghaly Marc-Alexandre <marc-alexandreghaly@catalyst-ca.net>
* @copyright 2022 Catalyst IT Australia Pty Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Binary from 'core/datafilter/filtertypes/binary';
export default class extends Binary {
}
@@ -0,0 +1,46 @@
<?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 bulk_delete_action is the base class for delete bulk actions ui.
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class bulk_delete_action extends \core_question\local\bank\bulk_action_base {
public function get_bulk_action_title(): string {
return get_string('delete');
}
public function get_key(): string {
return 'deleteselected';
}
public function get_bulk_action_url(): \moodle_url {
return new \moodle_url('/question/bank/deletequestion/delete.php');
}
public function get_bulk_action_capabilities(): ?array {
return [
'moodle/question:editall',
];
}
}
@@ -0,0 +1,106 @@
<?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/>.
/**
* Action to delete (or hide) a question, or restore a previously hidden question.
*
* @package qbank_deletequestion
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace qbank_deletequestion;
use core_question\local\bank\question_version_status;
use core_question\local\bank\question_action_base;
/**
* Action to delete (or hide) a question, or restore a previously hidden question.
*
* @package qbank_deletequestion
* @copyright 2009 Tim Hunt
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_action extends question_action_base {
/**
* @var string $strdelete
*/
protected $strdelete;
/**
* @var string $strrestore
*/
protected $strrestore;
/**
* Contains the url of the delete question page.
* @var \moodle_url|string
*/
public $deletequestionurl;
/**
* Array of the return parameters.
* @var array $returnparams
*/
protected $returnparams;
public function init(): void {
parent::init();
$this->strdelete = get_string('delete');
$this->strrestore = get_string('restore');
$this->deletequestionurl = new \moodle_url('/question/bank/deletequestion/delete.php');
if (!empty($this->qbank->cm->id)) {
$this->returnparams['cmid'] = $this->qbank->cm->id;
}
if (!empty($this->qbank->course->id)) {
$this->returnparams['courseid'] = $this->qbank->course->id;
}
if (!empty($this->qbank->returnurl)) {
$this->returnparams['returnurl'] = $this->qbank->returnurl;
}
}
public function get_menu_position(): int {
return 400;
}
protected function get_url_icon_and_label(\stdClass $question): array {
if (!question_has_capability_on($question, 'edit')) {
return [null, null, null];
}
if ($question->status === question_version_status::QUESTION_STATUS_HIDDEN) {
$hiddenparams = array(
'unhide' => $question->id,
'sesskey' => sesskey());
$hiddenparams = array_merge($hiddenparams, $this->returnparams);
$url = new \moodle_url($this->deletequestionurl, $hiddenparams);
return [$url, 't/restore', $this->strrestore];
} else {
$deleteparams = array(
'deleteselected' => $question->id,
'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];
}
}
}
@@ -0,0 +1,122 @@
<?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;
$questionversions = [];
$countselectedquestion = count($questionids);
if ($deleteallversions) {
$versionsofeachquestionbankentry = \question_bank::get_all_versions_of_questions($questionids);
foreach ($versionsofeachquestionbankentry as $entryid => $versions) {
// Re-order to oldest first.
$versionsofeachquestionbankentry[$entryid] = array_reverse($versions, true);
// Flip the array to list question by question id. [ qid => version ].
$questionversions += array_flip($versions);
}
// Flatten an array.
$questionids = array_merge(...$versionsofeachquestionbankentry);
}
// Get the names of all the questions.
$questions = $DB->get_records_list('question', 'id', $questionids, '', 'id, name');
// Build the message.
foreach ($questionids as $questionid) {
if (questions_in_use([$questionid])) {
$questionnames .= '* ';
$inuse = true;
}
$questionname = format_string($questions[$questionid]->name);
if (isset($questionversions[$questionid])) {
$a = new \stdClass();
$a->name = $questionname;
$a->version = $questionversions[$questionid];
$questionnames .= get_string('questionnameandquestionversion',
'question', $a) . '<br />';
} else {
$questionnames .= $questionname . '<br />';
}
}
// Add the in-use message if required.
if ($inuse) {
$questionnames .= '<br />'.get_string('questionsinuse', 'question');
}
// Add in the right tile and message text.
$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);
}
}
}
@@ -0,0 +1,72 @@
<?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;
use core\output\datafilter;
use core_question\local\bank\condition;
use core_question\local\bank\question_version_status;
/**
* This class controls whether hidden / deleted questions are hidden in the list.
*
* @package qbank_deletequestion
* @copyright 2013 Ray Morris
* @author 2021 Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hidden_condition extends condition {
public static function get_condition_key() {
return 'hidden';
}
/**
* Build query from filter value
*
* @param array $filter filter properties
* @return array where sql and params
*/
public static function build_query_from_filter(array $filter): array {
$showhidden = (bool)$filter['values'][0];
$where = "";
$params = [];
if (!$showhidden) {
$where = "qv.status <> :hidden_condition";
$params = ['hidden_condition' => question_version_status::QUESTION_STATUS_HIDDEN];
}
return [$where, $params];
}
public function get_title() {
return get_string('showhidden', 'core_question');
}
public function get_join_list(): array {
return [
datafilter::JOINTYPE_ANY,
];
}
public function get_filter_class() {
return 'qbank_deletequestion/datafilter/filtertypes/hidden';
}
public function is_required(): bool {
return true;
}
}
@@ -0,0 +1,58 @@
<?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/>.
/**
* Plugin entrypoint for columns.
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace qbank_deletequestion;
use core_question\local\bank\bulk_action_base;
use core_question\local\bank\plugin_features_base;
use core_question\local\bank\view;
/**
* Class columns is the entrypoint for the columns.
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugin_feature extends plugin_features_base {
public function get_question_actions($qbank): array {
return [
new delete_action($qbank),
];
}
public function get_bulk_actions(): array {
return [
new bulk_delete_action(),
];
}
public function get_question_filters(view $qbank = null): array {
return [
new hidden_condition($qbank),
];
}
}
@@ -0,0 +1,39 @@
<?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/>.
/**
* Version information for qbank_deletequestion.
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace qbank_deletequestion\privacy;
/**
* Privacy Subsystem for qbank_deletequestion implementing null_provider.
*
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+130
View File
@@ -0,0 +1,130 @@
<?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/>.
/**
* Delete question page.
*
* This code is based on question/classes/bank/view.php
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../config.php');
require_once(__DIR__ . '/../../editlib.php');
global $DB, $OUTPUT, $PAGE, $COURSE;
$deleteselected = optional_param('deleteselected', false, PARAM_BOOL);
$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);
}
\core_question\local\bank\helper::require_plugin_enabled('qbank_deletequestion');
if ($cmid) {
list($module, $cm) = get_module_from_cmid($cmid);
require_login($cm->course, false, $cm);
$thiscontext = context_module::instance($cmid);
} else if ($courseid) {
require_login($courseid, false);
$thiscontext = context_course::instance($courseid);
} else {
throw new moodle_exception('missingcourseorcmid', 'question');
}
$contexts = new core_question\local\bank\question_edit_contexts($thiscontext);
$url = new moodle_url('/question/bank/deletequestion/delete.php');
$PAGE->set_url($url);
$streditingquestions = get_string('deletequestion', 'qbank_deletequestion');
$PAGE->set_title($streditingquestions);
$PAGE->set_heading($COURSE->fullname);
$PAGE->activityheader->disable();
$PAGE->set_secondary_active_tab("questionbank");
// Unhide a question.
if (($unhide = optional_param('unhide', '', PARAM_INT)) and confirm_sesskey()) {
question_require_capability_on($unhide, 'edit');
$DB->set_field('question_versions', 'status',
\core_question\local\bank\question_version_status::QUESTION_STATUS_READY, ['questionid' => $unhide]);
// Purge these questions from the cache.
\question_bank::notify_question_edited($unhide);
redirect($returnurl);
}
// If user has already confirmed the action.
if ($deleteselected && ($confirm = optional_param('confirm', '', PARAM_ALPHANUM))
&& confirm_sesskey()) {
$deleteselected = required_param('deleteselected', PARAM_RAW);
if ($confirm == md5($deleteselected)) {
if ($questionlist = explode(',', $deleteselected)) {
\qbank_deletequestion\helper::delete_questions($questionlist, $deleteall);
}
redirect($returnurl);
} else {
throw new \moodle_exception('invalidconfirm', 'question');
}
}
echo $OUTPUT->header();
if ($deleteselected) {
// 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.
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 (!$questionlist) { // No questions were selected.
redirect($returnurl);
}
$questionlist = rtrim($questionlist, ',');
$deleteurl = new \moodle_url(
'/question/bank/deletequestion/delete.php',
[
'deleteselected' => $questionlist,
'deleteall' => $deleteall,
'confirm' => md5($questionlist),
'sesskey' => sesskey(),
'returnurl' => $returnurl->out_as_local_url(false),
'cmid' => $cmid,
'courseid' => $courseid,
],
);
$continue = new \single_button($deleteurl, get_string('delete'), 'post');
$questionids = explode(',', $questionlist);
[$displayoptions, $message] = qbank_deletequestion\helper::get_delete_confirmation_message($questionids,
$deleteall);
echo $OUTPUT->confirm($message, $continue, $returnurl, $displayoptions);
}
echo $OUTPUT->footer();
@@ -0,0 +1,28 @@
<?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/>.
/**
* Strings for component qbank_deletequestion, language 'en'
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Delete question';
$string['privacy:metadata'] = 'The Delete question question bank plugin does not store any personal data.';
$string['deletequestion'] = 'Delete selected question';
@@ -0,0 +1,33 @@
{{!
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/>.
}}
{{!
@template qbank_deletequestion/hidden_condition_advanced
Example context (json):
{
"displaydata": [
{
"checked": "checked attribute"
}
]
}
}}
<div class="hidden_condition_advanced">
<input type="hidden" name="showhidden" value="0" id="showhidden_off">
<input id="showhidden_on" class="searchoptions mr-1" type="checkbox" value="1" name="showhidden" {{{checked}}}>
<label for="showhidden_on">{{#str}} showhidden, question{{/str}}</label>
</div>
@@ -0,0 +1,71 @@
@qbank @qbank_deletequestion
Feature: Use the qbank plugin manager page for deletequestion
In order to check the plugin behaviour with enable and disable
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "activities" exist:
| activity | name | course | idnumber |
| quiz | Test quiz | C1 | quiz1 |
And the following "question categories" exist:
| contextlevel | reference | name |
| Course | C1 | Test questions |
And the following "questions" exist:
| questioncategory | qtype | name | questiontext |
| Test questions | truefalse | First question | Answer the first question |
| Test questions | truefalse | First question second | Answer the first question |
Scenario: Enable/disable delete question column from the base view
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I should see "Delete question"
And I click on "Disable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "mod_quiz > question bank" page
Then the "Delete" action should not exist for the "First question" question in the question bank
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "mod_quiz > question bank" page
And the "Delete" action should exist for the "First question" question in the question bank
@javascript
Scenario: Enable/disable delete questions bulk action from the base view
Given I log in as "admin"
When I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I should see "Delete question"
And I click on "Disable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "mod_quiz > question bank" page
And I click on "With selected" "button"
Then I should not see question bulk action "deleteselected"
And I navigate to "Plugins > Question bank plugins > Manage question bank plugins" in site administration
And I click on "Enable" "link" in the "Delete question" "table_row"
And I am on the "Test quiz" "mod_quiz > question bank" page
And I click on "With selected" "button"
And I should see question bulk action "deleteselected"
@javascript
Scenario: I should not see the deleted questions in the base view
Given I am on the "Test quiz" "mod_quiz > question bank" page logged in as "admin"
And I click on "First question" "checkbox"
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 "Delete questions?" "dialogue"
Then I should not see "First question"
And I should not see "First question second"
@javascript
Scenario: I should be able to delete a question when filtered using tags
Given I am on the "First question" "core_question > edit" page logged in as "admin"
And I set the following fields to these values:
| Tags | foo |
And I click on "Save changes" "button"
And I am on the "Test quiz" "mod_quiz > question bank" page
And I apply question bank filter "Tag" with value "foo"
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 "Delete question?" "dialogue"
Then I should not see "Third question"
And "foo" "autocomplete_selection" should exist
@@ -0,0 +1,177 @@
<?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;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
/**
* Class containing unit tests for the helper class
*
* @package qbank_deletequestion
* @copyright 2023 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class helper_test extends \advanced_testcase {
/**
* @var \context_module module context.
*/
protected $context;
/**
* @var \stdClass course object.
*/
protected $course;
/**
* @var \component_generator_base question generator.
*/
protected $qgenerator;
/**
* @var \stdClass quiz object.
*/
protected $quiz;
/**
* Called before every test.
*/
protected function setUp(): void {
parent::setUp();
self::setAdminUser();
$this->resetAfterTest();
$datagenerator = $this->getDataGenerator();
$this->course = $datagenerator->create_course();
$this->quiz = $datagenerator->create_module('quiz', ['course' => $this->course->id]);
$this->qgenerator = $datagenerator->get_plugin_generator('core_question');
$this->context = \context_module::instance($this->quiz->cmid);
}
/**
* Test get a confirmation message when deleting the question in the (question bank/history) page.
*
* @covers \qbank_deletequestion\helper::get_delete_confirmation_message
*/
public function test_get_delete_confirmation_message(): void {
$qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
$question = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id,
'name' => 'Question 1']);
$questionfirstversionid = $question->id;
// Verify confirmation title and confirmation message with question not in use in question bank page.
$deleteallversions = true;
[$title1, $message1] = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionfirstversionid],
$deleteallversions);
$this->assertEquals(['confirmtitle' => get_string('deletequestiontitle', 'question')],
$title1);
$this->assertEquals(get_string('deletequestioncheck', 'question',
$question->name). ' v1' . '<br />', $message1);
// Create a new version and adding it to a quiz.
$question2 = $this->qgenerator->update_question($question, null, ['name' => 'Question 1']);
$questionsecondversionid = $question2->id;
// Verify confirmation title and confirmation message with question has multiple versions in question bank page.
$listnameofquestionversion2 = $question->name . ' v1' . '<br />' . $question2->name . ' v2' .'<br />';
[$title2, $message2] = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionsecondversionid],
$deleteallversions);
$this->assertEquals(['confirmtitle' => get_string('deletequestiontitle', 'question')],
$title2);
$this->assertEquals(get_string('deletequestioncheck', 'question',
$listnameofquestionversion2), $message2);
// Verify confirmation title and confirmation message with multiple question selected.
$listnameofquestionversion3 = $question->name . ' v1' . '<br />' . $question2->name . ' v2' .'<br />';
[$title3, $message3] = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionfirstversionid,
$questionsecondversionid], $deleteallversions);
$this->assertEquals(['confirmtitle' => get_string('deletequestiontitle_plural', 'question')],
$title3);
$this->assertEquals(get_string('deletequestionscheck', 'question',
$listnameofquestionversion3), $message3);
// Add second question version to the quiz to become question in use.
quiz_add_quiz_question($questionsecondversionid, $this->quiz);
// Verify confirmation message with question in use and has multiple versions in question bank page.
$listnameofquestionversion4 = $question->name . ' v1' . '<br />' . '* ' . $question2->name . ' v2' . '<br />';
$message4 = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionsecondversionid],
$deleteallversions)[1];
$this->assertEquals(get_string('deletequestioncheck', 'question',
$listnameofquestionversion4) . '<br />' . get_string('questionsinuse',
'question'), $message4);
// Verify confirmation title and confirmation message in history page with one question selected.
$deleteallversions = false;
[$title5, $message5] = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionfirstversionid],
$deleteallversions);
$this->assertEquals(['confirmtitle' => get_string('deleteversiontitle', 'question')],
$title5);
$this->assertEquals(get_string('deleteselectedquestioncheck', 'question',
$question->name) . '<br />', $message5);
// Verify confirmation title and confirmation message in history page with multiple question selected.
$listnameofquestionversion6 = 'Question 1<br />* Question 1<br />';
[$title6, $message6] = \qbank_deletequestion\helper::get_delete_confirmation_message([$questionfirstversionid,
$questionsecondversionid], $deleteallversions);
$this->assertEquals(['confirmtitle' => get_string('deleteversiontitle_plural', 'question')],
$title6);
$this->assertEquals(get_string('deleteselectedquestioncheck', 'question',
$listnameofquestionversion6) . '<br />'. get_string('questionsinuse', 'question'),
$message6);
}
/**
* Test delete questions have single/multiple version.
*
* @covers \qbank_deletequestion\helper::delete_questions
*/
public function test_delete_question_has_multiple_version(): void {
global $DB;
$qcategory = $this->qgenerator->create_question_category(['contextid' => $this->context->id]);
$question1 = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id,
'name' => 'Question 1 version 1']);
$question1v1id = $question1->id;
// Create a new version for question 1.
$question1v2 = $this->qgenerator->update_question($question1, null, ['name' => 'Question 1 version 2']);
$question1v2id = $question1v2->id;
$question2 = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id,
'name' => 'Question 2 version 1']);
$question2v1id = $question2->id;
$question3 = $this->qgenerator->create_question('shortanswer', null, ['category' => $qcategory->id,
'name' => 'Question 3 version 1']);
$question3v1id = $question3->id;
// Do.
\qbank_deletequestion\helper::delete_questions([$question1v2id, $question2v1id], true);
// All the versions of question1 will be deleted.
$this->assertFalse($DB->record_exists('question', ['id' => $question1v1id]));
$this->assertFalse($DB->record_exists('question', ['id' => $question1v2id]));
// The question2 have single version will be deleted.
$this->assertFalse($DB->record_exists('question', ['id' => $question2v1id]));
// Check that we did not delete too much.
$this->assertTrue($DB->record_exists('question', ['id' => $question3v1id]));
}
}
+31
View File
@@ -0,0 +1,31 @@
<?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/>.
/**
* Version information for qbank_deletequestion.
*
* @package qbank_deletequestion
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Safat Shahin <safatshahin@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'qbank_deletequestion';
$plugin->version = 2024042200;
$plugin->requires = 2024041600;
$plugin->maturity = MATURITY_STABLE;