Merge branch 'MDL-82542-404' of https://github.com/NashTechOpenUniversity/moodle into MOODLE_404_STABLE
This commit is contained in:
@@ -76,7 +76,8 @@ class custom_view extends \core_question\local\bank\view {
|
||||
$params['filter']['category'] = [
|
||||
'jointype' => custom_category_condition::JOINTYPE_DEFAULT,
|
||||
'values' => [$category->id],
|
||||
'filteroptions' => ['includesubcategories' => false],
|
||||
'filteroptions' => ['includesubcategories' =>
|
||||
get_user_preferences('qbank_managecategories_includesubcategories_filter_default', false)],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
define("qbank_managecategories/datafilter/filtertypes/categories",["exports","core/datafilter/filtertype","core/templates"],(function(_exports,_filtertype,_templates){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_filtertype=_interopRequireDefault(_filtertype),_templates=_interopRequireDefault(_templates);class _default extends _filtertype.default{constructor(filterType,rootNode,initialValues){let filterOptions=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{includesubcategories:!1};var obj,key,value;super(filterType,rootNode,initialValues),value={includeSubcategories:"input[name=category-subcategories]"},(key="SELECTORS")in(obj=this)?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,this.addSubcategoryCheckbox(filterOptions.includesubcategories)}async addSubcategoryCheckbox(){let checked=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const filterValueNode=this.getFilterValueNode(),{html:html}=await _templates.default.renderForPromise("qbank_managecategories/include_subcategories_checkbox",{checked:checked});filterValueNode.insertAdjacentHTML("afterend",html)}get filterOptions(){return[{name:"includesubcategories",value:this.filterRoot.querySelector(this.SELECTORS.includeSubcategories).checked}]}get filterValue(){return{name:this.name,jointype:this.jointype,values:this.values,filteroptions:this.filterOptions}}}return _exports.default=_default,_exports.default}));
|
||||
define("qbank_managecategories/datafilter/filtertypes/categories",["exports","core/datafilter/filtertype","core/templates","core_user/repository"],(function(_exports,_filtertype,_templates,_repository){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_filtertype=_interopRequireDefault(_filtertype),_templates=_interopRequireDefault(_templates);class _default extends _filtertype.default{constructor(filterType,rootNode,initialValues){let filterOptions=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{includesubcategories:!1};var obj,key,value;super(filterType,rootNode,initialValues),value={includeSubcategories:"input[name=category-subcategories]"},(key="SELECTORS")in(obj=this)?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,this.addSubcategoryCheckbox(filterOptions.includesubcategories)}async addSubcategoryCheckbox(){let checked=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;const filterValueNode=this.getFilterValueNode();null==checked?checked=await(0,_repository.getUserPreference)("qbank_managecategories_includesubcategories_filter_default"):(0,_repository.setUserPreference)("qbank_managecategories_includesubcategories_filter_default",checked);const{html:html}=await _templates.default.renderForPromise("qbank_managecategories/include_subcategories_checkbox",{checked:checked&&"0"!==checked});filterValueNode.insertAdjacentHTML("afterend",html)}get filterOptions(){return[{name:"includesubcategories",value:this.filterRoot.querySelector(this.SELECTORS.includeSubcategories).checked}]}get filterValue(){return{name:this.name,jointype:this.jointype,values:this.values,filteroptions:this.filterOptions}}}return _exports.default=_default,_exports.default}));
|
||||
|
||||
//# sourceMappingURL=categories.min.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"categories.min.js","sources":["../../../src/datafilter/filtertypes/categories.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 display of subcategories questions.\n *\n * @module qbank_managecategories/datafilter/filtertypes/categories\n * @author Mark Johnson <[email protected]>\n * @copyright 2023 Catalyst IT Europe Ltd.\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport GenericFilter from 'core/datafilter/filtertype';\nimport Templates from 'core/templates';\n\nexport default class extends GenericFilter {\n\n SELECTORS = {\n includeSubcategories: 'input[name=category-subcategories]',\n };\n\n /**\n * Construct a new categoires filter\n *\n * @param {String} filterType The type of filter that this relates to (categories)\n * @param {HTMLElement} rootNode The root node for the participants filterset\n * @param {Array} initialValues The currently selected category IDs.\n * @param {Object} filterOptions An object containing the additional options for the filter, currently \"includesubcategories\"\n * is supported, which if true will display the \"Also show questions from subcategories\" checkbox as checked.\n */\n constructor(filterType, rootNode, initialValues, filterOptions = {includesubcategories: false}) {\n super(filterType, rootNode, initialValues);\n this.addSubcategoryCheckbox(filterOptions.includesubcategories);\n }\n\n async addSubcategoryCheckbox(checked = false) {\n const filterValueNode = this.getFilterValueNode();\n const {html} = await Templates.renderForPromise('qbank_managecategories/include_subcategories_checkbox', {\n checked: checked,\n });\n filterValueNode.insertAdjacentHTML('afterend', html);\n }\n\n get filterOptions() {\n return [\n {name: 'includesubcategories', value: this.filterRoot.querySelector(this.SELECTORS.includeSubcategories).checked}\n ];\n }\n\n get filterValue() {\n return {\n name: this.name,\n jointype: this.jointype,\n values: this.values,\n filteroptions: this.filterOptions,\n };\n }\n}\n"],"names":["GenericFilter","constructor","filterType","rootNode","initialValues","filterOptions","includesubcategories","includeSubcategories","addSubcategoryCheckbox","checked","filterValueNode","this","getFilterValueNode","html","Templates","renderForPromise","insertAdjacentHTML","name","value","filterRoot","querySelector","SELECTORS","filterValue","jointype","values","filteroptions"],"mappings":"8bA2B6BA,oBAezBC,YAAYC,WAAYC,SAAUC,mBAAeC,qEAAgB,CAACC,sBAAsB,2BAC9EJ,WAAYC,SAAUC,qBAdpB,CACRG,qBAAsB,+KAcjBC,uBAAuBH,cAAcC,yDAGjBG,sEACnBC,gBAAkBC,KAAKC,sBACvBC,KAACA,YAAcC,mBAAUC,iBAAiB,wDAAyD,CACrGN,QAASA,UAEbC,gBAAgBM,mBAAmB,WAAYH,MAG/CR,0BACO,CACH,CAACY,KAAM,uBAAwBC,MAAOP,KAAKQ,WAAWC,cAAcT,KAAKU,UAAUd,sBAAsBE,UAI7Ga,wBACO,CACHL,KAAMN,KAAKM,KACXM,SAAUZ,KAAKY,SACfC,OAAQb,KAAKa,OACbC,cAAed,KAAKN"}
|
||||
{"version":3,"file":"categories.min.js","sources":["../../../src/datafilter/filtertypes/categories.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 display of subcategories questions.\n *\n * @module qbank_managecategories/datafilter/filtertypes/categories\n * @author Mark Johnson <[email protected]>\n * @copyright 2023 Catalyst IT Europe Ltd.\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport GenericFilter from 'core/datafilter/filtertype';\nimport Templates from 'core/templates';\nimport {getUserPreference, setUserPreference} from 'core_user/repository';\n\nexport default class extends GenericFilter {\n\n SELECTORS = {\n includeSubcategories: 'input[name=category-subcategories]',\n };\n\n /**\n * Construct a new categoires filter\n *\n * @param {String} filterType The type of filter that this relates to (categories)\n * @param {HTMLElement} rootNode The root node for the participants filterset\n * @param {Array} initialValues The currently selected category IDs.\n * @param {Object} filterOptions An object containing the additional options for the filter, currently \"includesubcategories\"\n * is supported, which if true will display the \"Also show questions from subcategories\" checkbox as checked.\n */\n constructor(filterType, rootNode, initialValues, filterOptions = {includesubcategories: false}) {\n super(filterType, rootNode, initialValues);\n this.addSubcategoryCheckbox(filterOptions.includesubcategories);\n }\n\n async addSubcategoryCheckbox(checked = null) {\n const filterValueNode = this.getFilterValueNode();\n if (checked === null || checked === undefined) {\n checked = await getUserPreference('qbank_managecategories_includesubcategories_filter_default');\n } else {\n setUserPreference('qbank_managecategories_includesubcategories_filter_default', checked);\n }\n const {html} = await Templates.renderForPromise('qbank_managecategories/include_subcategories_checkbox', {\n checked: checked && checked !== '0',\n });\n filterValueNode.insertAdjacentHTML('afterend', html);\n }\n\n get filterOptions() {\n return [\n {name: 'includesubcategories', value: this.filterRoot.querySelector(this.SELECTORS.includeSubcategories).checked}\n ];\n }\n\n get filterValue() {\n return {\n name: this.name,\n jointype: this.jointype,\n values: this.values,\n filteroptions: this.filterOptions,\n };\n }\n}\n"],"names":["GenericFilter","constructor","filterType","rootNode","initialValues","filterOptions","includesubcategories","includeSubcategories","addSubcategoryCheckbox","checked","filterValueNode","this","getFilterValueNode","html","Templates","renderForPromise","insertAdjacentHTML","name","value","filterRoot","querySelector","SELECTORS","filterValue","jointype","values","filteroptions"],"mappings":"ieA4B6BA,oBAezBC,YAAYC,WAAYC,SAAUC,mBAAeC,qEAAgB,CAACC,sBAAsB,2BAC9EJ,WAAYC,SAAUC,qBAdpB,CACRG,qBAAsB,+KAcjBC,uBAAuBH,cAAcC,yDAGjBG,+DAAU,WAC7BC,gBAAkBC,KAAKC,qBACzBH,MAAAA,QACAA,cAAgB,iCAAkB,gGAEhB,6DAA8DA,eAE9EI,KAACA,YAAcC,mBAAUC,iBAAiB,wDAAyD,CACrGN,QAASA,SAAuB,MAAZA,UAExBC,gBAAgBM,mBAAmB,WAAYH,MAG/CR,0BACO,CACH,CAACY,KAAM,uBAAwBC,MAAOP,KAAKQ,WAAWC,cAAcT,KAAKU,UAAUd,sBAAsBE,UAI7Ga,wBACO,CACHL,KAAMN,KAAKM,KACXM,SAAUZ,KAAKY,SACfC,OAAQb,KAAKa,OACbC,cAAed,KAAKN"}
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
import GenericFilter from 'core/datafilter/filtertype';
|
||||
import Templates from 'core/templates';
|
||||
import {getUserPreference, setUserPreference} from 'core_user/repository';
|
||||
|
||||
export default class extends GenericFilter {
|
||||
|
||||
@@ -45,10 +46,15 @@ export default class extends GenericFilter {
|
||||
this.addSubcategoryCheckbox(filterOptions.includesubcategories);
|
||||
}
|
||||
|
||||
async addSubcategoryCheckbox(checked = false) {
|
||||
async addSubcategoryCheckbox(checked = null) {
|
||||
const filterValueNode = this.getFilterValueNode();
|
||||
if (checked === null || checked === undefined) {
|
||||
checked = await getUserPreference('qbank_managecategories_includesubcategories_filter_default');
|
||||
} else {
|
||||
setUserPreference('qbank_managecategories_includesubcategories_filter_default', checked);
|
||||
}
|
||||
const {html} = await Templates.renderForPromise('qbank_managecategories/include_subcategories_checkbox', {
|
||||
checked: checked,
|
||||
checked: checked && checked !== '0',
|
||||
});
|
||||
filterValueNode.insertAdjacentHTML('afterend', html);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,12 @@ class category_condition extends condition {
|
||||
$this->category = self::get_category_record($categoryid, $contextid);
|
||||
|
||||
parent::__construct($qbank);
|
||||
$this->includesubcategories = $this->filter['filteroptions']['includesubcategories'] ?? false;
|
||||
if (isset($this->filter['filteroptions']['includesubcategories'])) {
|
||||
set_user_preference('qbank_managecategories_includesubcategories_filter_default',
|
||||
$this->filter['filteroptions']['includesubcategories']);
|
||||
}
|
||||
$this->includesubcategories = $this->filter['filteroptions']['includesubcategories'] ??
|
||||
get_user_preferences('qbank_managecategories_includesubcategories_filter_default', false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace qbank_managecategories\privacy;
|
||||
|
||||
use core_privacy\local\metadata\collection;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
/**
|
||||
* Privacy Subsystem for qbank_managecategories implementing null_provider.
|
||||
*
|
||||
@@ -25,14 +28,36 @@ namespace qbank_managecategories\privacy;
|
||||
* @author Guillermo Gomez Arias <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\core_privacy\local\request\user_preference_provider {
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
* Returns meta data about this system.
|
||||
*
|
||||
* @return string
|
||||
* @param collection $collection The initialised collection to add items to.
|
||||
* @return collection A listing of user data stored through this system.
|
||||
*/
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
public static function get_metadata(collection $collection): collection {
|
||||
$collection->add_user_preference('qbank_managecategories_includesubcategories_filter_default',
|
||||
'privacy:preference:includesubcategories_filter_default');
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user preferences for the plugin.
|
||||
*
|
||||
* @param int $userid The userid of the user whose data is to be exported.
|
||||
*/
|
||||
public static function export_user_preferences(int $userid) {
|
||||
$includesubcategories = get_user_preferences('qbank_managecategories_includesubcategories_filter_default', null, $userid);
|
||||
if (isset($includesubcategories)) {
|
||||
$displayquestions = $includesubcategories ? 'questionsubcategoriesdisplayed' : 'questionsubcategoriesnotdisplayed';
|
||||
writer::export_user_preference(
|
||||
'qbank_managecategories',
|
||||
'includesubcategories',
|
||||
$includesubcategories,
|
||||
get_string($displayquestions, 'qbank_managecategories')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,6 @@
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'Manage categories';
|
||||
$string['privacy:metadata'] = 'The Manage categories question bank plugin does not store any personal data.';
|
||||
$string['privacy:preference:includesubcategories_filter_default'] = 'Indicates whether or not the "Also show questions from subcategories" filter option is enabled by default when the user views the question bank.';
|
||||
$string['questionsubcategoriesdisplayed'] = 'When selecting categories in the question bank, the "Also show questions from subcategories" option is used and are automatically included in the filter results.';
|
||||
$string['questionsubcategoriesnotdisplayed'] = 'When selecting categories in the question bank, the "Also show questions from subcategories" option is not used, so questions from subcategories are not included in the filter results.';
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Callbacks for qbank_manageacategories
|
||||
*
|
||||
* @package qbank_managecategories
|
||||
* @copyright 2024 Catalyst IT Europe Ltd
|
||||
* @author Mark Johnson <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allow update of user preferences via AJAX.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
function qbank_managecategories_user_preferences(): array {
|
||||
return [
|
||||
'qbank_managecategories_includesubcategories_filter_default' => [
|
||||
'type' => PARAM_BOOL,
|
||||
'null' => NULL_NOT_ALLOWED,
|
||||
'default' => false,
|
||||
'permissioncallback' => [core_user::class, 'is_current_user'],
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -102,3 +102,23 @@ Feature: A teacher can put questions in categories in the question bank
|
||||
When I reload the page
|
||||
Then I should see "Question 1" in the "categoryquestions" "table"
|
||||
And the field "Also show questions from subcategories" matches value "1"
|
||||
And I am on the "Course 1" "core_question > course question bank" page
|
||||
And the field "Also show questions from subcategories" matches value "1"
|
||||
|
||||
Scenario: Filter question by category and subcategories in Quiz question page
|
||||
Given the following "activities" exist:
|
||||
| activity | name | course | idnumber |
|
||||
| quiz | Test quiz | C1 | quiz1 |
|
||||
And I am on the "Test quiz" "mod_quiz > Edit" page
|
||||
And I open the "last" add to quiz menu
|
||||
And I follow "from question bank"
|
||||
When I set the field "Also show questions from subcategories" to "1"
|
||||
And I click on "Apply filters" "button"
|
||||
Then I should see "Question 1" in the "categoryquestions" "table"
|
||||
And I set the field "Also show questions from subcategories" to "0"
|
||||
And I click on "Apply filters" "button"
|
||||
And I should not see "Question 1"
|
||||
And I click on "Close" "button" in the "Add from the question bank at the end" "dialogue"
|
||||
And I open the "last" add to quiz menu
|
||||
And I follow "from question bank"
|
||||
And the field "Also show questions from subcategories" matches value "0"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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_managecategories\privacy;
|
||||
|
||||
use advanced_testcase;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
/**
|
||||
* Unit tests for qbank_managecategories privacy provider.
|
||||
*
|
||||
* @package qbank_managecategories
|
||||
* @copyright 2021 Catalyst IT Australia Pty Ltd
|
||||
* @author 2021, Ghaly Marc-Alexandre <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \qbank_managecategories\privacy\provider
|
||||
*/
|
||||
final class provider_test extends advanced_testcase {
|
||||
/**
|
||||
* Test to check export_user_preferences.
|
||||
*
|
||||
* @covers ::export_user_preferences
|
||||
*/
|
||||
public function test_export_user_preferences(): void {
|
||||
$this->resetAfterTest();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
set_user_preference('qbank_managecategories_includesubcategories_filter_default', 1, $user);
|
||||
provider::export_user_preferences($user->id);
|
||||
$writer = writer::with_context(\context_system::instance());
|
||||
$prefs = $writer->get_user_preferences('qbank_managecategories');
|
||||
$this->assertEquals(1, $prefs->includesubcategories->value);
|
||||
$this->assertEquals(get_string('questionsubcategoriesdisplayed',
|
||||
'qbank_managecategories'), $prefs->includesubcategories->description);
|
||||
}
|
||||
}
|
||||
@@ -244,7 +244,8 @@ class view {
|
||||
$params['filter']['category'] = [
|
||||
'jointype' => category_condition::JOINTYPE_DEFAULT,
|
||||
'values' => [$category->id],
|
||||
'filteroptions' => ['includesubcategories' => false],
|
||||
'filteroptions' => ['includesubcategories' =>
|
||||
get_user_preferences('qbank_managecategories_includesubcategories_filter_default', false)],
|
||||
];
|
||||
}
|
||||
$params['filter']['hidden'] = [
|
||||
|
||||
Reference in New Issue
Block a user