Skip to content

Commit 97443e9

Browse files
committed
MDL-83859 qbank_viewquestiontype: Add type filter
This adds a new question bank filter for filtering by question type. The filter can be applied with one or multiple question types, and can either include or exclude the selected types.
1 parent fa4c9e8 commit 97443e9

File tree

7 files changed

+219
-2
lines changed

7 files changed

+219
-2
lines changed

question/bank/viewquestiontype/amd/build/datafilter/filtertype/type.min.js

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

question/bank/viewquestiontype/amd/build/datafilter/filtertype/type.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// This file is part of Moodle - http://moodle.org/
2+
//
3+
// Moodle is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// Moodle is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15+
16+
/**
17+
* Filter managing hidden questions.
18+
*
19+
* @module qbank_viewquestiontype/datafilter/filtertypes/type
20+
* @author Mark Johnson <[email protected]>
21+
* @copyright 2024 Catalyst IT Europe Ltd
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
import Filter from 'core/datafilter/filtertype';
26+
27+
export default class extends Filter {
28+
/**
29+
* Get the list of values for this filter type.
30+
*
31+
* Overrides the default behaviour of running parseInt on the raw values, since we have textual
32+
* plugin identifiers and not numeric IDs.
33+
*
34+
* @returns {Array}
35+
*/
36+
get values() {
37+
return this.rawValues;
38+
}
39+
}

question/bank/viewquestiontype/classes/plugin_feature.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace qbank_viewquestiontype;
1818

1919
use core_question\local\bank\plugin_features_base;
20+
use core_question\local\bank\view;
2021

2122
/**
2223
* Class plugin_feature is the entrypoint for the columns.
@@ -27,10 +28,17 @@
2728
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2829
*/
2930
class plugin_feature extends plugin_features_base {
30-
31+
#[\Override]
3132
public function get_question_columns($qbank): array {
3233
return [
33-
new question_type_column($qbank)
34+
new question_type_column($qbank),
35+
];
36+
}
37+
38+
#[\Override]
39+
public function get_question_filters(?view $qbank = null): array {
40+
return [
41+
new type_condition($qbank),
3442
];
3543
}
3644
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
namespace qbank_viewquestiontype;
18+
19+
use question_bank;
20+
use core\output\datafilter;
21+
use core_question\local\bank\condition;
22+
23+
/**
24+
* Filter condition for question type
25+
*
26+
* @package qbank_viewquestiontype
27+
* @copyright 2024 onwards Catalyst IT EU {@link https://catalyst-eu.net}
28+
* @author Mark Johnson <[email protected]>
29+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30+
*/
31+
class type_condition extends condition {
32+
#[\Override]
33+
public static function get_condition_key() {
34+
return 'qtype';
35+
}
36+
37+
#[\Override]
38+
public function get_title() {
39+
return get_string('typefilter', 'qbank_viewquestiontype');
40+
}
41+
42+
#[\Override]
43+
public function get_filter_class() {
44+
return 'qbank_viewquestiontype/datafilter/filtertype/type';
45+
}
46+
47+
#[\Override]
48+
public function allow_custom() {
49+
return false;
50+
}
51+
52+
/**
53+
* Get the list of available joins for the filter.
54+
*
55+
* Questions can be ANY or NONE of the selected types. Since questions cannot have multiple types,
56+
* allowing "ALL" does not make sense here.
57+
*
58+
* @return array
59+
*/
60+
public function get_join_list(): array {
61+
return [
62+
datafilter::JOINTYPE_NONE,
63+
datafilter::JOINTYPE_ANY,
64+
];
65+
}
66+
67+
/**
68+
* Build a list of the available question types.
69+
*
70+
* @return array
71+
*/
72+
public function get_initial_values(): array {
73+
$types = question_bank::get_all_qtypes();
74+
$values = [];
75+
foreach ($types as $plugin => $type) {
76+
$values[] = [
77+
'value' => $plugin,
78+
'title' => get_string('pluginname', 'qtype_' . $plugin),
79+
];
80+
}
81+
usort($values, fn($a, $b) => $a['title'] <=> $b['title']);
82+
return $values;
83+
}
84+
85+
/**
86+
* Build a WHERE condition to filter the q.qtype column by the selected question types.
87+
*
88+
* @param array $filter
89+
* @return array
90+
* @throws \coding_exception
91+
* @throws \dml_exception
92+
*/
93+
public static function build_query_from_filter(array $filter): array {
94+
global $DB;
95+
96+
// Remove empty string.
97+
$filter['values'] = array_filter($filter['values']);
98+
99+
$selectedtypes = $filter['values'] ?? [];
100+
101+
$params = [];
102+
$where = '';
103+
$jointype = $filter['jointype'] ?? self::JOINTYPE_DEFAULT;
104+
if ($selectedtypes) {
105+
// If we are matching NONE rather than ANY, exclude the selected types instead.
106+
$equal = !($jointype === datafilter::JOINTYPE_NONE);
107+
[$typesql, $params] = $DB->get_in_or_equal($selectedtypes, SQL_PARAMS_NAMED, 'param', $equal);
108+
$where = "q.qtype $typesql";
109+
}
110+
return [$where, $params];
111+
}
112+
}

question/bank/viewquestiontype/lang/en/qbank_viewquestiontype.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2424
*/
2525

26+
$string['typefilter'] = 'Type';
2627
$string['pluginname'] = 'View question type';
2728
$string['privacy:metadata'] = 'The View question type question bank plugin does not store any personal data.';
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@qbank @qbank_viewquestiontype @javascript
2+
Feature: Filter questions by type
3+
As a teacher
4+
In order to organise my questions
5+
I want to filter the list of questions by type
6+
7+
Background:
8+
Given the following "courses" exist:
9+
| fullname | shortname | category |
10+
| Course 1 | C1 | 0 |
11+
And the following "activities" exist:
12+
| activity | name | intro | course | idnumber |
13+
| qbank | Qbank 1 | Question bank 1 | C1 | qbank1 |
14+
And the following "question categories" exist:
15+
| contextlevel | reference | name |
16+
| Activity module | qbank1 | Test questions |
17+
And the following "questions" exist:
18+
| questioncategory | qtype | name | questiontext |
19+
| Test questions | truefalse | First question | Answer the first question |
20+
| Test questions | numerical | Second question | Answer the second question |
21+
| Test questions | essay | Third question | Answer the third question |
22+
23+
Scenario: Filter by a single type
24+
Given I am on the "Qbank 1" "core_question > question bank" page logged in as "admin"
25+
When I apply question bank filter "Type" with value "True/False"
26+
Then I should see "First question"
27+
And I should not see "Second question"
28+
And I should not see "Third question"
29+
30+
Scenario: Filter by multiple types
31+
Given I am on the "Qbank 1" "core_question > question bank" page logged in as "admin"
32+
When I apply question bank filter "Type" with value "True/False, Essay"
33+
Then I should see "First question"
34+
And I should not see "Second question"
35+
And I should see "Third question"
36+
37+
Scenario: Exclude types by filter
38+
Given I am on the "Qbank 1" "core_question > question bank" page logged in as "admin"
39+
When I add question bank filter "Type"
40+
And I set the field "Type" to "True/False, Essay"
41+
And I set the field "Match" in the "Filter 3" "fieldset" to "None"
42+
And I press "Apply filters"
43+
Then I should not see "First question"
44+
And I should see "Second question"
45+
And I should not see "Third question"

0 commit comments

Comments
 (0)