MDL-72716 blocks: fix external fetching of available blocks.

Pass `$PAGE->subpage` value in AJAX request, which is required on
some pages (e.g. user dashboard) for loading existing blocks.
This commit is contained in:
Paul Holden 2021-12-01 08:13:30 +00:00
parent f8eb36373d
commit 844f4a7fb3
7 changed files with 29 additions and 15 deletions

View File

@ -54,7 +54,8 @@ class fetch_addable_blocks extends external_api {
[
'pagecontextid' => new external_value(PARAM_INT, 'The context ID of the page.'),
'pagetype' => new external_value(PARAM_ALPHANUMEXT, 'The type of the page.'),
'pagelayout' => new external_value(PARAM_ALPHA, 'The layout of the page.')
'pagelayout' => new external_value(PARAM_ALPHA, 'The layout of the page.'),
'subpage' => new external_value(PARAM_TEXT, 'The subpage identifier', VALUE_DEFAULT, ''),
]
);
}
@ -65,16 +66,18 @@ class fetch_addable_blocks extends external_api {
* @param int $pagecontextid The context ID of the page
* @param string $pagetype The type of the page
* @param string $pagelayout The layout of the page
* @param string $subpage The subpage identifier
* @return array The blocks list
*/
public static function execute(int $pagecontextid, string $pagetype, string $pagelayout): array {
public static function execute(int $pagecontextid, string $pagetype, string $pagelayout, string $subpage = ''): array {
global $PAGE;
$params = self::validate_parameters(self::execute_parameters(),
[
'pagecontextid' => $pagecontextid,
'pagetype' => $pagetype,
'pagelayout' => $pagelayout
'pagelayout' => $pagelayout,
'subpage' => $subpage,
]
);
@ -85,6 +88,8 @@ class fetch_addable_blocks extends external_api {
// We need to manually set the page layout and page type.
$PAGE->set_pagelayout($params['pagelayout']);
$PAGE->set_pagetype($params['pagetype']);
$PAGE->set_subpage($params['subpage']);
// Firstly, we need to load all currently existing page blocks to later determine which blocks are addable.
$PAGE->blocks->load_blocks(false);
$PAGE->blocks->create_all_block_instances();

View File

@ -6,6 +6,8 @@ information provided here is intended especially for developers.
* Block block_quiz_results has been completely removed from core.
The Quiz results block is hidden by default since Moodle 2.9. It is recommended to use the Activity results block instead, which works with any type of activity (not just quizzes).
* External function core_block::get_dashboard_blocks has a new parameter to indicate if you want to receive the block on the my/courses page.
* The `core_block_fetch_addable_blocks` external method accepts an optional `subpage` parameter, in order to correctly
calculate available blocks for pages that use this property (e.g. the user dashboard)
=== 3.8 ===
* Block block_community is no longer a part of core.

View File

@ -1,2 +1,2 @@
define ("core/addblockmodal",["exports","core/modal_factory","core/templates","core/str","core/ajax"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=f(b);c=f(c);e=f(e);function f(a){return a&&a.__esModule?a:{default:a}}function g(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function h(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function f(a){g(i,d,e,f,h,"next",a)}function h(a){g(i,d,e,f,h,"throw",a)}f(void 0)})}}var i={ADD_BLOCK:"[data-key=\"addblock\"]"},j=!1,k=function(a,b,c){document.addEventListener("click",function(d){var e=d.target.closest(i.ADD_BLOCK);if(e){d.preventDefault();var f=null,g=null!==c&&void 0!==c?c:e.dataset.url;l().then(function(c){f=c;var d=m(g,a,b);c.setBody(d);c.show();return d}).catch(function(){f.destroy()})}})},l=function(){return b.default.create({type:b.default.types.CANCEL,title:(0,d.get_string)("addblock")})},m=function(){var a=h(regeneratorRuntime.mark(function a(b,d,e){var f;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return n(d,e);case 2:f=a.sent;return a.abrupt("return",c.default.render("core/add_block_body",{blocks:f,url:b}));case 4:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),n=function(){var a=h(regeneratorRuntime.mark(function a(b,c){var d;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:M.cfg.contextid,pagetype:b,pagelayout:c}};return a.abrupt("return",e.default.call([d])[0]);case 2:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),o=function(a,b){var c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!j){k(a,b,c);j=!0}};a.init=o});
define ("core/addblockmodal",["exports","core/modal_factory","core/templates","core/str","core/ajax"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=f(b);c=f(c);e=f(e);function f(a){return a&&a.__esModule?a:{default:a}}function g(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function h(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function f(a){g(i,d,e,f,h,"next",a)}function h(a){g(i,d,e,f,h,"throw",a)}f(void 0)})}}var i={ADD_BLOCK:"[data-key=\"addblock\"]"},j=!1,k=function(a,b,c,d){document.addEventListener("click",function(f){var e=f.target.closest(i.ADD_BLOCK);if(e){f.preventDefault();var g=null,h=null!==c&&void 0!==c?c:e.dataset.url;l().then(function(c){g=c;var e=m(h,a,b,d);c.setBody(e);c.show();return e}).catch(function(){g.destroy()})}})},l=function(){return b.default.create({type:b.default.types.CANCEL,title:(0,d.get_string)("addblock")})},m=function(){var a=h(regeneratorRuntime.mark(function a(b,d,e,f){var g;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:a.next=2;return n(d,e,f);case 2:g=a.sent;return a.abrupt("return",c.default.render("core/add_block_body",{blocks:g,url:b}));case 4:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),n=function(){var a=h(regeneratorRuntime.mark(function a(b,c,d){var f;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:f={methodname:"core_block_fetch_addable_blocks",args:{pagecontextid:M.cfg.contextid,pagetype:b,pagelayout:c,subpage:d}};return a.abrupt("return",e.default.call([f])[0]);case 2:case"end":return a.stop();}}},a)}));return function(){return a.apply(this,arguments)}}(),o=function(a,b){var c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null,d=3<arguments.length&&arguments[3]!==void 0?arguments[3]:"";if(!j){k(a,b,c,d);j=!0}};a.init=o});
//# sourceMappingURL=addblockmodal.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -40,8 +40,9 @@ let listenerEventsRegistered = false;
* @param {String} pageType The type of the page
* @param {String} pageLayout The layout of the page
* @param {String|null} addBlockUrl The add block URL
* @param {String} subPage The subpage identifier
*/
const registerListenerEvents = (pageType, pageLayout, addBlockUrl) => {
const registerListenerEvents = (pageType, pageLayout, addBlockUrl, subPage) => {
document.addEventListener('click', e => {
const addBlock = e.target.closest(SELECTORS.ADD_BLOCK);
@ -54,7 +55,7 @@ const registerListenerEvents = (pageType, pageLayout, addBlockUrl) => {
buildAddBlockModal()
.then(modal => {
addBlockModal = modal;
const modalBody = renderBlocks(addBlockModalUrl, pageType, pageLayout);
const modalBody = renderBlocks(addBlockModalUrl, pageType, pageLayout, subPage);
modal.setBody(modalBody);
modal.show();
@ -87,11 +88,12 @@ const buildAddBlockModal = () => {
* @param {String} addBlockUrl The add block URL
* @param {String} pageType The type of the page
* @param {String} pageLayout The layout of the page
* @param {String} subPage The subpage identifier
* @return {Promise}
*/
const renderBlocks = async(addBlockUrl, pageType, pageLayout) => {
const renderBlocks = async(addBlockUrl, pageType, pageLayout, subPage) => {
// Fetch all addable blocks in the given page.
const blocks = await getAddableBlocks(pageType, pageLayout);
const blocks = await getAddableBlocks(pageType, pageLayout, subPage);
return Templates.render('core/add_block_body', {
blocks: blocks,
@ -105,15 +107,17 @@ const renderBlocks = async(addBlockUrl, pageType, pageLayout) => {
* @method getAddableBlocks
* @param {String} pageType The type of the page
* @param {String} pageLayout The layout of the page
* @param {String} subPage The subpage identifier
* @return {Promise}
*/
const getAddableBlocks = async(pageType, pageLayout) => {
const getAddableBlocks = async(pageType, pageLayout, subPage) => {
const request = {
methodname: 'core_block_fetch_addable_blocks',
args: {
pagecontextid: M.cfg.contextid,
pagetype: pageType,
pagelayout: pageLayout
pagelayout: pageLayout,
subpage: subPage,
},
};
@ -127,10 +131,11 @@ const getAddableBlocks = async(pageType, pageLayout) => {
* @param {String} pageType The type of the page
* @param {String} pageLayout The layout of the page
* @param {String|null} addBlockUrl The add block URL
* @param {String} subPage The subpage identifier
*/
export const init = (pageType, pageLayout, addBlockUrl = null) => {
export const init = (pageType, pageLayout, addBlockUrl = null, subPage = '') => {
if (!listenerEventsRegistered) {
registerListenerEvents(pageType, pageLayout, addBlockUrl);
registerListenerEvents(pageType, pageLayout, addBlockUrl, subPage);
listenerEventsRegistered = true;
}
};

View File

@ -4973,6 +4973,7 @@ EOD;
'escapedlink' => "?{$url->get_query_string(false)}",
'pageType' => $this->page->pagetype,
'pageLayout' => $this->page->pagelayout,
'subPage' => $this->page->subpage,
]
);
}

View File

@ -24,7 +24,8 @@
"link" : "/my/index.php?bui_addblock&bui_blockregion=content&sesskey=M3mes",
"escapedlink" : "?bui_addblock&bui_blockregion=content&sesskey=M3mes",
"pageType" : "my-index",
"pageLayout" : "mydashboard"
"pageLayout" : "mydashboard",
"subPage": "15"
}
}}
@ -37,6 +38,6 @@
{{#js}}
// Initialise the JS for the modal window which displays the blocks available to add.
require(['core/addblockmodal'], function(addBlockModal) {
addBlockModal.init('{{pageType}}', '{{pageLayout}}');
addBlockModal.init('{{pageType}}', '{{pageLayout}}', null, '{{subPage}}');
});
{{/js}}