mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 00:42:54 +02:00
MDL-74054 qbank_columnsortorder: Progressively enhance question bank actions
This modifies the question_data fragment used by the filter code to make its parameters closer to the URL parameters of the question/edit.php page. This Allows us to progressively enhance the add, remove and reset actions on the question bank page, using this same fragment to reload the question table after each change. This re-uses the same actions.js module used for enhancing these actions on the qbank_columnsortorder admin screen.
This commit is contained in:
parent
3685a3355f
commit
63894ec2fe
@ -2549,15 +2549,22 @@ function mod_quiz_output_fragment_question_data(array $args): string {
|
||||
$thispageurl = new \moodle_url('/mod/quiz/edit.php', ['cmid' => $cmid]);
|
||||
$thiscontext = \context_module::instance($cmid);
|
||||
$contexts = new \core_question\local\bank\question_edit_contexts($thiscontext);
|
||||
$defaultcategory = question_make_default_categories($contexts->all());
|
||||
$params['cat'] = implode(',', [$defaultcategory->id, $defaultcategory->contextid]);
|
||||
|
||||
$course = get_course($params['courseid']);
|
||||
[, $cm] = get_module_from_cmid($cmid);
|
||||
$params['tabname'] = 'questions';
|
||||
|
||||
// Custom question bank View.
|
||||
$viewclass = clean_param($args['view'], PARAM_NOTAGS);
|
||||
$questionbank = new $viewclass($contexts, $thispageurl, $course, $cm, $params, $extraparams);
|
||||
|
||||
// Question table.
|
||||
return $questionbank->display_questions_table();
|
||||
$questionbank->add_standard_search_conditions();
|
||||
ob_start();
|
||||
$questionbank->display_question_list();
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
|
2
question/amd/build/filter.min.js
vendored
2
question/amd/build/filter.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -70,7 +70,9 @@ export const init = (
|
||||
|
||||
const filterSet = document.querySelector(`#${filterRegionId}`);
|
||||
|
||||
const filterCondition = {
|
||||
const viewData = {
|
||||
view: view,
|
||||
cmid: cmid,
|
||||
cat: defaultcategoryid,
|
||||
courseid: defaultcourseid,
|
||||
filter: {},
|
||||
@ -78,12 +80,14 @@ export const init = (
|
||||
qpage: 0,
|
||||
qperpage: perpage,
|
||||
sortdata: {},
|
||||
tabname: 'questions',
|
||||
extraparams: extraparams,
|
||||
lastchanged: document.querySelector(SELECTORS.LASTCHANGED_FIELD)?.value ?? null,
|
||||
};
|
||||
|
||||
let sortData = {};
|
||||
const defaultSort = document.querySelector(SELECTORS.QUESTION_TABLE)?.dataset?.defaultsort;
|
||||
if (defaultSort) {
|
||||
filterCondition.sortData = JSON.parse(defaultSort);
|
||||
sortData = JSON.parse(defaultSort);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,25 +101,20 @@ export const init = (
|
||||
// use the default category filter condition.
|
||||
if (filterdata) {
|
||||
// Main join types.
|
||||
filterCondition.jointype = parseInt(filterSet.dataset.filterverb, 10);
|
||||
viewData.jointype = parseInt(filterSet.dataset.filterverb, 10);
|
||||
delete filterdata.jointype;
|
||||
// Retrieve filter info.
|
||||
filterCondition.filter = filterdata;
|
||||
viewData.filter = filterdata;
|
||||
if (Object.keys(filterdata).length !== 0) {
|
||||
if (!isNaN(filterCondition.jointype)) {
|
||||
filterdata.jointype = filterCondition.jointype;
|
||||
if (!isNaN(viewData.jointype)) {
|
||||
filterdata.jointype = viewData.jointype;
|
||||
}
|
||||
updateUrlParams(filterdata);
|
||||
}
|
||||
}
|
||||
// Load questions for first page.
|
||||
const viewData = {
|
||||
view: view,
|
||||
cmid: cmid,
|
||||
filtercondition: JSON.stringify(filterCondition),
|
||||
extraparams: extraparams,
|
||||
lastchanged: document.querySelector(SELECTORS.LASTCHANGED_FIELD)?.value ?? null
|
||||
};
|
||||
viewData.filter = JSON.stringify(filterdata);
|
||||
viewData.sortdata = JSON.stringify(sortData);
|
||||
Fragment.loadFragment(component, callback, contextId, viewData)
|
||||
// Render questions for first page and pagination.
|
||||
.then((questionhtml, jsfooter) => {
|
||||
@ -126,7 +125,7 @@ export const init = (
|
||||
if (jsfooter === undefined) {
|
||||
jsfooter = '';
|
||||
}
|
||||
Templates.replaceNodeContents(questionscontainer, questionhtml, jsfooter);
|
||||
Templates.replaceNode(questionscontainer, questionhtml, jsfooter);
|
||||
// Resolve filter promise.
|
||||
if (pendingPromise) {
|
||||
pendingPromise.resolve();
|
||||
@ -187,15 +186,15 @@ export const init = (
|
||||
const clearLink = e.target.closest(Selectors.filterset.actions.resetFilters);
|
||||
if (sortableLink) {
|
||||
e.preventDefault();
|
||||
const oldSort = filterCondition.sortdata;
|
||||
filterCondition.sortdata = {};
|
||||
filterCondition.sortdata[sortableLink.dataset.sortname] = sortableLink.dataset.sortorder;
|
||||
const oldSort = sortData;
|
||||
sortData = {};
|
||||
sortData[sortableLink.dataset.sortname] = sortableLink.dataset.sortorder;
|
||||
for (const sortname in oldSort) {
|
||||
if (sortname !== sortableLink.dataset.sortname) {
|
||||
filterCondition.sortdata[sortname] = oldSort[sortname];
|
||||
sortData[sortname] = oldSort[sortname];
|
||||
}
|
||||
}
|
||||
filterCondition.qpage = 0;
|
||||
viewData.qpage = 0;
|
||||
coreFilter.updateTableFromFilter();
|
||||
}
|
||||
if (paginationLink) {
|
||||
@ -203,7 +202,7 @@ export const init = (
|
||||
const paginationURL = new URL(paginationLink.getAttribute("href"));
|
||||
const qpage = paginationURL.searchParams.get('qpage');
|
||||
if (paginationURL.search !== null) {
|
||||
filterCondition.qpage = qpage;
|
||||
viewData.qpage = qpage;
|
||||
coreFilter.updateTableFromFilter();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ define("qbank_columnsortorder/actions",["exports","core/sortable_list","jquery",
|
||||
* @copyright 2023 onwards Catalyst IT Europe Ltd
|
||||
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupSortableLists=_exports.setupActionButtons=_exports.getColumnOrder=_exports.SELECTORS=void 0,_sortable_list=_interopRequireDefault(_sortable_list),_jquery=_interopRequireDefault(_jquery),repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(repository),_notification=_interopRequireDefault(_notification),_fragment=_interopRequireDefault(_fragment),_templates=_interopRequireDefault(_templates);const SELECTORS={columnList:".qbank-column-list",sortableColumn:".qbank-sortable-column",removeLink:"[data-action=remove]",moveHandler:"[data-drag-type=move]",addColumn:".addcolumn",addLink:"[data-action=add]",actionLink:".action-link"};_exports.SELECTORS=SELECTORS;_exports.setupSortableLists=function(listRoot){let vertical=arguments.length>1&&void 0!==arguments[1]&&arguments[1],global=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const sortableList=new _sortable_list.default(listRoot,{moveHandlerSelector:SELECTORS.moveHandler,isHorizontal:!vertical});sortableList.getElementName=element=>Promise.resolve(element.data("name"));const sortableColumns=(0,_jquery.default)(SELECTORS.sortableColumn);return sortableColumns.on(_sortable_list.default.EVENTS.DROP,(()=>{repository.setColumnbankOrder(getColumnOrder(listRoot),global).catch(_notification.default.exception),listRoot.querySelectorAll(SELECTORS.sortableColumn).forEach((item=>item.classList.remove("active")))})),sortableColumns.on(_sortable_list.default.EVENTS.DRAGSTART,(event=>{event.currentTarget.classList.add("active")})),sortableColumns};_exports.setupActionButtons=function(uiRoot){let global=arguments.length>1&&void 0!==arguments[1]&&arguments[1];uiRoot.addEventListener("click",(async e=>{const actionLink=e.target.closest(SELECTORS.actionLink);if(actionLink)try{e.preventDefault();const action=actionLink.dataset.action;if("add"===action||"remove"===action){const hiddenColumns=[],addColumnList=document.querySelector(SELECTORS.addColumn);addColumnList&&addColumnList.querySelectorAll(SELECTORS.addLink).forEach((item=>{"add"===action&&item===actionLink||hiddenColumns.push(item.dataset.column)})),"remove"===action&&hiddenColumns.push(actionLink.dataset.column),await repository.setHiddenColumns(hiddenColumns,global)}else"reset"===action&&await Promise.all([repository.setColumnbankOrder([],global),repository.setHiddenColumns([],global),repository.setColumnSize("",global)]);const fragmentData=uiRoot.dataset;_fragment.default.loadFragment(fragmentData.component,fragmentData.callback,fragmentData.contextid).then(((html,js)=>_templates.default.replaceNode(uiRoot,html,js))).catch(_notification.default.exception)}catch(ex){await _notification.default.exception(ex)}}))};const getColumnOrder=listRoot=>{const columns=Array.from(listRoot.querySelectorAll("[data-columnid]")).map((column=>column.dataset.columnid));return columns.filter(((value,index)=>columns.indexOf(value)===index))};_exports.getColumnOrder=getColumnOrder}));
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setupSortableLists=_exports.setupActionButtons=_exports.getColumnOrder=_exports.SELECTORS=void 0,_sortable_list=_interopRequireDefault(_sortable_list),_jquery=_interopRequireDefault(_jquery),repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(repository),_notification=_interopRequireDefault(_notification),_fragment=_interopRequireDefault(_fragment),_templates=_interopRequireDefault(_templates);const SELECTORS={columnList:".qbank-column-list",sortableColumn:".qbank-sortable-column",removeLink:"[data-action=remove]",moveHandler:"[data-drag-type=move]",addColumn:".addcolumn",addLink:"[data-action=add]",actionLink:".action-link"};_exports.SELECTORS=SELECTORS;_exports.setupSortableLists=function(listRoot){let vertical=arguments.length>1&&void 0!==arguments[1]&&arguments[1],global=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const sortableList=new _sortable_list.default(listRoot,{moveHandlerSelector:SELECTORS.moveHandler,isHorizontal:!vertical});sortableList.getElementName=element=>Promise.resolve(element.data("name"));const sortableColumns=(0,_jquery.default)(SELECTORS.sortableColumn);return sortableColumns.on(_sortable_list.default.EVENTS.DROP,(()=>{repository.setColumnbankOrder(getColumnOrder(listRoot),global).catch(_notification.default.exception),listRoot.querySelectorAll(SELECTORS.sortableColumn).forEach((item=>item.classList.remove("active")))})),sortableColumns.on(_sortable_list.default.EVENTS.DRAGSTART,(event=>{event.currentTarget.classList.add("active")})),sortableColumns};_exports.setupActionButtons=function(uiRoot){let global=arguments.length>1&&void 0!==arguments[1]&&arguments[1];uiRoot.addEventListener("click",(async e=>{const actionLink=e.target.closest(SELECTORS.actionLink);if(actionLink)try{e.preventDefault();const action=actionLink.dataset.action;if("add"===action||"remove"===action){const hiddenColumns=[],addColumnList=document.querySelector(SELECTORS.addColumn);addColumnList&&addColumnList.querySelectorAll(SELECTORS.addLink).forEach((item=>{"add"===action&&item===actionLink||hiddenColumns.push(item.dataset.column)})),"remove"===action&&hiddenColumns.push(actionLink.dataset.column),await repository.setHiddenColumns(hiddenColumns,global)}else"reset"===action&&await Promise.all([repository.setColumnbankOrder([],global),repository.setHiddenColumns([],global),repository.setColumnSize("",global)]);const fragmentData=uiRoot.dataset,actionUrl=new URL(actionLink.href),returnUrl=new URL(actionUrl.searchParams.get("returnurl").replaceAll("&","&")),viewData={},sortData={};returnUrl&&returnUrl.searchParams.forEach(((value,key)=>{const sortItem=key.match(/sortdata\[([^\]]+)\]/);sortItem?sortData[sortItem.pop()]=value:viewData[key]=value})),viewData.sortdata=JSON.stringify(sortData),_fragment.default.loadFragment(fragmentData.component,fragmentData.callback,fragmentData.contextid,viewData).then(((html,js)=>_templates.default.replaceNode(uiRoot,html,js))).catch(_notification.default.exception)}catch(ex){await _notification.default.exception(ex)}}))};const getColumnOrder=listRoot=>{const columns=Array.from(listRoot.querySelectorAll("[data-columnid]")).map((column=>column.dataset.columnid));return columns.filter(((value,index)=>columns.indexOf(value)===index))};_exports.getColumnOrder=getColumnOrder}));
|
||||
|
||||
//# sourceMappingURL=actions.min.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -109,8 +109,26 @@ export const setupActionButtons = (uiRoot, global = false) => {
|
||||
]);
|
||||
}
|
||||
const fragmentData = uiRoot.dataset;
|
||||
const actionUrl = new URL(actionLink.href);
|
||||
const returnUrl = new URL(actionUrl.searchParams.get('returnurl').replaceAll('&', '&'));
|
||||
const viewData = {};
|
||||
const sortData = {};
|
||||
if (returnUrl) {
|
||||
returnUrl.searchParams.forEach((value, key) => {
|
||||
// Match keys like 'sortdata[fieldname]' and convert them to an array,
|
||||
// because the fragment API doesn't like non-alphanum argument keys.
|
||||
const sortItem = key.match(/sortdata\[([^\]]+)\]/);
|
||||
if (sortItem) {
|
||||
// The item returned by sortItem.pop() is the contents of the matching group, the field name.
|
||||
sortData[sortItem.pop()] = value;
|
||||
} else {
|
||||
viewData[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
viewData.sortdata = JSON.stringify(sortData);
|
||||
// We have to use then() there, as loadFragment doesn't appear to work with await.
|
||||
Fragment.loadFragment(fragmentData.component, fragmentData.callback, fragmentData.contextid)
|
||||
Fragment.loadFragment(fragmentData.component, fragmentData.callback, fragmentData.contextid, viewData)
|
||||
.then((html, js) => {
|
||||
return Templates.replaceNode(uiRoot, html, js);
|
||||
})
|
||||
|
@ -349,7 +349,7 @@ const reorderColumns = event => {
|
||||
* column sorting, then enable the move and resize modals to be triggered from menu actions.
|
||||
*/
|
||||
export const init = async() => {
|
||||
const uiRoot = document.querySelector('.questionbankwindow');
|
||||
const uiRoot = document.getElementById('questionscontainer');
|
||||
await addHandleContainers(uiRoot);
|
||||
setUpMoveHandles(uiRoot.querySelectorAll(SELECTORS.moveAction));
|
||||
setUpResizeHandles(uiRoot);
|
||||
@ -364,4 +364,5 @@ export const init = async() => {
|
||||
});
|
||||
setUpMoveActions(uiRoot);
|
||||
setUpResizeActions(uiRoot);
|
||||
actions.setupActionButtons(uiRoot);
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ class column_action_remove extends column_action_base {
|
||||
'column' => $column->get_column_id(),
|
||||
'action' => 'remove',
|
||||
'sesskey' => sesskey(),
|
||||
'returnurl' => $this->qbank->returnurl,
|
||||
'returnurl' => new \moodle_url($this->qbank->returnurl),
|
||||
]);
|
||||
if ($this->global) {
|
||||
$actionurl->param('global', $this->global);
|
||||
|
@ -37,16 +37,23 @@ class filter_condition_manager {
|
||||
* @return array the param and extra param
|
||||
*/
|
||||
public static function extract_parameters_from_fragment_args(array $args): array {
|
||||
global $DB;
|
||||
// Decode query string.
|
||||
$filtercondition = json_decode($args['filtercondition'], true);
|
||||
$categories = $DB->get_records('question_categories', ['id' => clean_param($filtercondition['cat'], PARAM_INT)]);
|
||||
$categories = \qbank_managecategories\helper::question_add_context_in_key($categories);
|
||||
$category = array_pop($categories);
|
||||
$filtercondition['cat'] = $category->id;
|
||||
$extraparams = json_decode($args['extraparams'], true);
|
||||
$params = [];
|
||||
if (array_key_exists('filter', $args)) {
|
||||
$params['filter'] = json_decode($args['filter'], true);
|
||||
}
|
||||
if (array_key_exists('cmid', $args)) {
|
||||
$params['cmid'] = $args['cmid'];
|
||||
}
|
||||
if (array_key_exists('courseid', $args)) {
|
||||
$params['courseid'] = $args['courseid'];
|
||||
}
|
||||
$params['jointype'] = $args['jointype'] ?? condition::JOINTYPE_DEFAULT;
|
||||
$params['qpage'] = $args['qpage'] ?? 0;
|
||||
$params['qperpage'] = $args['qperpage'] ?? 100;
|
||||
$params['sortdata'] = json_decode($args['sortdata'] ?? '', true);
|
||||
$extraparams = json_decode($args['extraparams'] ?? '', true);
|
||||
|
||||
return [$filtercondition, $extraparams];
|
||||
return [$params, $extraparams];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,6 +201,9 @@ function question_edit_setup($edittab, $baseurl, $requirecmid = false, $unused =
|
||||
// Category list page.
|
||||
$params['cpage'] = optional_param('cpage', null, PARAM_INT);
|
||||
|
||||
// Sort data.
|
||||
$params['sortdata'] = optional_param_array('sortdata', [], PARAM_INT);
|
||||
|
||||
$PAGE->set_pagelayout('admin');
|
||||
|
||||
return question_build_edit_resources($edittab, $baseurl, $params);
|
||||
@ -247,7 +250,7 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
$thispageurl->remove_all_params(); // We are going to explicity add back everything important - this avoids unwanted params from being retained.
|
||||
|
||||
$cleanparams = [
|
||||
'qsorts' => [],
|
||||
'sortdata' => [],
|
||||
'filter' => null
|
||||
];
|
||||
$paramtypes = [
|
||||
@ -258,7 +261,6 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
'category' => PARAM_SEQUENCE,
|
||||
'qperpage' => PARAM_INT,
|
||||
'cpage' => PARAM_INT,
|
||||
'qbshowtext' => PARAM_INT,
|
||||
];
|
||||
|
||||
foreach ($paramtypes as $name => $type) {
|
||||
@ -276,6 +278,10 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
$cleanparams['filter'] = $params['filter'];
|
||||
}
|
||||
|
||||
if (isset($params['sortdata'])) {
|
||||
$cleanparams['sortdata'] = clean_param_array($params['sortdata'], PARAM_INT);
|
||||
}
|
||||
|
||||
$cmid = $cleanparams['cmid'];
|
||||
$courseid = $cleanparams['courseid'];
|
||||
$qpage = $cleanparams['qpage'] ?: -1;
|
||||
@ -283,7 +289,6 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
$category = $cleanparams['category'] ?: 0;
|
||||
$qperpage = $cleanparams['qperpage'];
|
||||
$cpage = $cleanparams['cpage'] ?: 1;
|
||||
$qsorts = $cleanparams['qsorts'];
|
||||
|
||||
if (is_null($cmid) && is_null($courseid)) {
|
||||
throw new \moodle_exception('Must provide a cmid or courseid');
|
||||
@ -293,16 +298,21 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
list($module, $cm) = get_module_from_cmid($cmid);
|
||||
$courseid = $cm->course;
|
||||
$thispageurl->params(compact('cmid'));
|
||||
require_login($courseid, false, $cm);
|
||||
$thiscontext = context_module::instance($cmid);
|
||||
} else {
|
||||
$module = null;
|
||||
$cm = null;
|
||||
$thispageurl->params(compact('courseid'));
|
||||
require_login($courseid, false);
|
||||
$thiscontext = context_course::instance($courseid);
|
||||
}
|
||||
|
||||
if (defined('AJAX_SCRIPT') && AJAX_SCRIPT) {
|
||||
// For AJAX, we don't need to set up the course page for output.
|
||||
require_login();
|
||||
} else {
|
||||
require_login($courseid, false, $cm);
|
||||
}
|
||||
|
||||
if ($thiscontext){
|
||||
$contexts = new core_question\local\bank\question_edit_contexts($thiscontext);
|
||||
$contexts->require_one_edit_tab_cap($edittab);
|
||||
@ -330,19 +340,6 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
navigation_node::override_active_url($thispageurl);
|
||||
}
|
||||
|
||||
// This need to occur after the override_active_url call above because
|
||||
// these values change on the page request causing the URLs to mismatch
|
||||
// when trying to work out the active node.
|
||||
for ($i = 1; $i <= core_question\local\bank\view::MAX_SORTS; $i++) {
|
||||
$param = 'qbs' . $i;
|
||||
if (isset($params[$param])) {
|
||||
$value = clean_param($params[$param], PARAM_TEXT);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
$thispageurl->param($param, $value);
|
||||
}
|
||||
|
||||
if ($pagevars['qpage'] > -1) {
|
||||
$thispageurl->param('qpage', $pagevars['qpage']);
|
||||
} else {
|
||||
@ -387,7 +384,7 @@ function question_build_edit_resources($edittab, $baseurl, $params,
|
||||
$pagevars['tabname'] = $edittab;
|
||||
|
||||
// Sort parameters.
|
||||
$pagevars['sortdata'] = optional_param_array('sortdata', [], PARAM_INT);
|
||||
$pagevars['sortdata'] = $cleanparams['sortdata'];
|
||||
foreach ($pagevars['sortdata'] as $sortname => $sortorder) {
|
||||
$thispageurl->param('sortdata[' . $sortname . ']', $sortorder);
|
||||
}
|
||||
|
@ -117,39 +117,33 @@ function core_question_output_fragment_tags_form($args) {
|
||||
* @return array|string
|
||||
*/
|
||||
function core_question_output_fragment_question_data(array $args): string {
|
||||
global $PAGE;
|
||||
if (empty($args)) {
|
||||
return '';
|
||||
}
|
||||
[$params, $extraparams] = \core_question\local\bank\filter_condition_manager::extract_parameters_from_fragment_args($args);
|
||||
$thiscontext = \context_course::instance($params['courseid']);
|
||||
$contexts = new \core_question\local\bank\question_edit_contexts($thiscontext);
|
||||
$contexts->require_one_edit_tab_cap($params['tabname']);
|
||||
$course = get_course($params['courseid']);
|
||||
[
|
||||
$thispageurl,
|
||||
$contexts,
|
||||
,
|
||||
$cm,
|
||||
,
|
||||
$pagevars
|
||||
] = question_build_edit_resources('questions', '/question/edit.php', $params);
|
||||
|
||||
if (is_null($cm)) {
|
||||
$course = get_course(clean_param($args['courseid'], PARAM_INT));
|
||||
} else {
|
||||
$course = get_course($cm->course);
|
||||
}
|
||||
|
||||
$viewclass = empty($args['view']) ? \core_question\local\bank\view::class : clean_param($args['view'], PARAM_NOTAGS);
|
||||
$cmid = clean_param($args['cmid'], PARAM_INT);
|
||||
[, $cm] = empty($cmid) ? [null, null] : get_module_from_cmid($cmid);
|
||||
|
||||
$nodeparent = $PAGE->settingsnav->find('questionbank', \navigation_node::TYPE_CONTAINER);
|
||||
$thispageurl = new \moodle_url($nodeparent->action);
|
||||
if ($cm) {
|
||||
$thispageurl->param('cmid', $cm->id);
|
||||
} else {
|
||||
$thispageurl->param('courseid', $params['courseid']);
|
||||
}
|
||||
if (!empty($args['filtercondition'])) {
|
||||
$thispageurl->param('filter', $args['filtercondition']);
|
||||
}
|
||||
if (!empty($args['lastchanged'])) {
|
||||
$thispageurl->param('lastchanged', $args['lastchanged']);
|
||||
$thispageurl->param('lastchanged', clean_param($args['lastchanged'], PARAM_INT));
|
||||
}
|
||||
if (!empty($params['sortdata'])) {
|
||||
foreach ($params['sortdata'] as $sortname => $sortorder) {
|
||||
$thispageurl->param('sortdata[' . $sortname . ']', $sortorder);
|
||||
}
|
||||
}
|
||||
$questionbank = new $viewclass($contexts, $thispageurl, $course, $cm, $params, $extraparams);
|
||||
// This is highly suspicious, but it is the same approach taken in /question/edit.php. See MDL-79281.
|
||||
$thispageurl->param('deleteall', 1);
|
||||
$questionbank = new $viewclass($contexts, $thispageurl, $course, $cm, $pagevars, $extraparams);
|
||||
$questionbank->add_standard_search_conditions();
|
||||
ob_start();
|
||||
$questionbank->display_question_list();
|
||||
|
Loading…
x
Reference in New Issue
Block a user