diff --git a/blocks/classes/external/fetch_addable_blocks.php b/blocks/classes/external/fetch_addable_blocks.php new file mode 100644 index 00000000000..3e14ae55eab --- /dev/null +++ b/blocks/classes/external/fetch_addable_blocks.php @@ -0,0 +1,118 @@ +. + +/** + * This is the external method used for fetching the addable blocks in a given page. + * + * @package core_block + * @since Moodle 3.11 + * @copyright 2020 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_block\external; + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->libdir . '/externallib.php'); + +use external_api; +use external_function_parameters; +use external_multiple_structure; +use external_single_structure; +use external_value; + +/** + * This is the external method used for fetching the addable blocks in a given page. + * + * @copyright 2020 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class fetch_addable_blocks extends external_api { + + /** + * Describes the parameters for execute. + * + * @return external_function_parameters + */ + public static function execute_parameters(): external_function_parameters { + return new external_function_parameters( + [ + 'pagecontextid' => new external_value(PARAM_INT, 'The context ID of the page.'), + 'pagetype' => new external_value(PARAM_ALPHAEXT, 'The type of the page.'), + 'pagelayout' => new external_value(PARAM_ALPHA, 'The layout of the page.') + ] + ); + } + + /** + * Fetch the addable blocks in a given page. + * + * @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 + * @return array The blocks list + */ + public static function execute(int $pagecontextid, string $pagetype, string $pagelayout): array { + global $PAGE; + + $params = self::validate_parameters(self::execute_parameters(), + [ + 'pagecontextid' => $pagecontextid, + 'pagetype' => $pagetype, + 'pagelayout' => $pagelayout + ] + ); + + $context = \context::instance_by_id($params['pagecontextid']); + // Validate the context. This will also set the context in $PAGE. + self::validate_context($context); + + // We need to manually set the page layout and page type. + $PAGE->set_pagelayout($params['pagelayout']); + $PAGE->set_pagetype($params['pagetype']); + // 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(); + + $addableblocks = $PAGE->blocks->get_addable_blocks(); + + return array_map(function($block) { + return [ + 'name' => $block->name, + 'title' => get_string('pluginname', "block_{$block->name}") + ]; + }, $addableblocks); + } + + /** + * Describes the execute return value. + * + * @return external_multiple_structure + */ + public static function execute_returns(): external_multiple_structure { + return new external_multiple_structure( + new external_single_structure( + [ + 'name' => new external_value(PARAM_PLUGIN, 'The name of the block.'), + 'title' => new external_value(PARAM_RAW, 'The title of the block.'), + ] + ), + 'List of addable blocks in a given page.' + ); + } +} diff --git a/lib/amd/build/addblockmodal.min.js b/lib/amd/build/addblockmodal.min.js index 350c0056473..830678757f5 100644 --- a/lib/amd/build/addblockmodal.min.js +++ b/lib/amd/build/addblockmodal.min.js @@ -1,2 +1,2 @@ -define ("core/addblockmodal",["jquery","core/modal_factory","core/templates","core/str","core/notification"],function(a,b,c,d,e){return{init:function init(f){var g=a("[data-key=addblock]"),h=f.blocks.map(function(a){return{key:"pluginname",component:"block_"+a}}),i=d.get_strings(h).then(function(a){return a.map(function(a,b){return{name:f.blocks[b],title:a}})}).then(function(a){f.blocks=a;return c.render("core/add_block_body",f)}).fail(e.exception),j=d.get_string("addblock").fail(e.exception);b.create({title:j,body:i,type:"CANCEL"},g)}}}); +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=null,k=function(a,b,c){document.addEventListener("click",function(d){if(d.target.closest(i.ADD_BLOCK)){d.preventDefault();if(j){j.show()}else{l().then(function(d){j=d;var e=m(c,a,b);d.setBody(e);d.show();return e}).catch(function(){j.destroy();j=null})}}})},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)}}();a.init=function init(a,b,c){k(a,b,c)}}); //# sourceMappingURL=addblockmodal.min.js.map diff --git a/lib/amd/build/addblockmodal.min.js.map b/lib/amd/build/addblockmodal.min.js.map index 839aaa57792..a433efc312f 100644 --- a/lib/amd/build/addblockmodal.min.js.map +++ b/lib/amd/build/addblockmodal.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/addblockmodal.js"],"names":["define","$","ModalFactory","Templates","Str","Notification","init","context","addblocklink","titlerequests","blocks","map","blockName","key","component","bodyPromise","get_strings","then","titles","title","index","name","render","fail","exception","titlePromise","get_string","create","body","type"],"mappings":"AAwBAA,OAAM,sBAAC,CAAC,QAAD,CAAW,oBAAX,CAAiC,gBAAjC,CAAmD,UAAnD,CAA+D,mBAA/D,CAAD,CACC,SAASC,CAAT,CAAYC,CAAZ,CAA0BC,CAA1B,CAAqCC,CAArC,CAA0CC,CAA1C,CAAwD,CAG3D,MAA+C,CAO3CC,IAAI,CAAE,cAASC,CAAT,CAAkB,IAChBC,CAAAA,CAAY,CAAGP,CAAC,CAAC,qBAAD,CADA,CAIhBQ,CAAa,CAAGF,CAAO,CAACG,MAAR,CAAeC,GAAf,CAAmB,SAASC,CAAT,CAAoB,CACvD,MAAO,CACHC,GAAG,CAAE,YADF,CAEHC,SAAS,CAAE,SAAWF,CAFnB,CAIV,CALmB,CAJA,CAWhBG,CAAW,CAAGX,CAAG,CAACY,WAAJ,CAAgBP,CAAhB,EACjBQ,IADiB,CACZ,SAASC,CAAT,CAAiB,CACnB,MAAOA,CAAAA,CAAM,CAACP,GAAP,CAAW,SAASQ,CAAT,CAAgBC,CAAhB,CAAuB,CACrC,MAAO,CACHC,IAAI,CAAEd,CAAO,CAACG,MAAR,CAAeU,CAAf,CADH,CAEHD,KAAK,CAAEA,CAFJ,CAIV,CALM,CAMV,CARiB,EASjBF,IATiB,CASZ,SAASP,CAAT,CAAiB,CACnBH,CAAO,CAACG,MAAR,CAAiBA,CAAjB,CACA,MAAOP,CAAAA,CAAS,CAACmB,MAAV,CAAiB,qBAAjB,CAAwCf,CAAxC,CACV,CAZiB,EAajBgB,IAbiB,CAaZlB,CAAY,CAACmB,SAbD,CAXE,CA0BhBC,CAAY,CAAGrB,CAAG,CAACsB,UAAJ,CAAe,UAAf,EAClBH,IADkB,CACblB,CAAY,CAACmB,SADA,CA1BC,CA6BpBtB,CAAY,CAACyB,MAAb,CAAoB,CAChBR,KAAK,CAAEM,CADS,CAEhBG,IAAI,CAAEb,CAFU,CAGhBc,IAAI,CAAE,QAHU,CAApB,CAIGrB,CAJH,CAKH,CAzC0C,CA2ClD,CA/CK,CAAN","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 .\n\n/**\n * Show an add block modal instead of doing it on a separate page.\n *\n * @module core/addblockmodal\n * @class addblockmodal\n * @package core\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/modal_factory', 'core/templates', 'core/str', 'core/notification'],\n function($, ModalFactory, Templates, Str, Notification) {\n\n\n return /** @alias module:core/addblockmodal */ {\n /**\n * Global init function for this module.\n *\n * @method init\n * @param {Object} context The template context for rendering this modal body.\n */\n init: function(context) {\n var addblocklink = $('[data-key=addblock]');\n\n // We need the fetch the names of the blocks. It was too much to send in the page.\n var titlerequests = context.blocks.map(function(blockName) {\n return {\n key: 'pluginname',\n component: 'block_' + blockName,\n };\n });\n\n var bodyPromise = Str.get_strings(titlerequests)\n .then(function(titles) {\n return titles.map(function(title, index) {\n return {\n name: context.blocks[index],\n title: title,\n };\n });\n })\n .then(function(blocks) {\n context.blocks = blocks;\n return Templates.render('core/add_block_body', context);\n })\n .fail(Notification.exception);\n\n var titlePromise = Str.get_string('addblock')\n .fail(Notification.exception);\n\n ModalFactory.create({\n title: titlePromise,\n body: bodyPromise,\n type: 'CANCEL',\n }, addblocklink);\n }\n };\n});\n"],"file":"addblockmodal.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/addblockmodal.js"],"names":["SELECTORS","ADD_BLOCK","addBlockModal","registerListenerEvents","pageType","pageLayout","addBlockUrl","document","addEventListener","e","target","closest","preventDefault","show","buildAddBlockModal","then","modal","modalBody","renderBlocks","setBody","catch","destroy","ModalFactory","create","type","types","CANCEL","title","getAddableBlocks","blocks","Templates","render","url","request","methodname","args","pagecontextid","M","cfg","contextid","pagetype","pagelayout","Ajax","call","init"],"mappings":"sMAyBA,OACA,OAEA,O,qXAEMA,CAAAA,CAAS,CAAG,CACdC,SAAS,CAAE,yBADG,C,CAIdC,CAAa,CAAG,I,CAUdC,CAAsB,CAAG,SAACC,CAAD,CAAWC,CAAX,CAAuBC,CAAvB,CAAuC,CAClEC,QAAQ,CAACC,gBAAT,CAA0B,OAA1B,CAAmC,SAAAC,CAAC,CAAI,CAEpC,GAAIA,CAAC,CAACC,MAAF,CAASC,OAAT,CAAiBX,CAAS,CAACC,SAA3B,CAAJ,CAA2C,CACvCQ,CAAC,CAACG,cAAF,GAEA,GAAIV,CAAJ,CAAmB,CAEfA,CAAa,CAACW,IAAd,EACH,CAHD,IAGO,CACHC,CAAkB,GACjBC,IADD,CACM,SAAAC,CAAK,CAAI,CACXd,CAAa,CAAGc,CAAhB,CACA,GAAMC,CAAAA,CAAS,CAAGC,CAAY,CAACZ,CAAD,CAAcF,CAAd,CAAwBC,CAAxB,CAA9B,CACAW,CAAK,CAACG,OAAN,CAAcF,CAAd,EACAD,CAAK,CAACH,IAAN,GAEA,MAAOI,CAAAA,CACV,CARD,EASCG,KATD,CASO,UAAM,CACTlB,CAAa,CAACmB,OAAd,GAEAnB,CAAa,CAAG,IACnB,CAbD,CAcH,CACJ,CACJ,CAzBD,CA0BH,C,CAQKY,CAAkB,CAAG,UAAM,CAC7B,MAAOQ,WAAaC,MAAb,CAAoB,CACvBC,IAAI,CAAEF,UAAaG,KAAb,CAAmBC,MADF,CAEvBC,KAAK,CAAE,iBAAU,UAAV,CAFgB,CAApB,CAIV,C,CAWKT,CAAY,4CAAG,WAAMZ,CAAN,CAAmBF,CAAnB,CAA6BC,CAA7B,wGAEIuB,CAAAA,CAAgB,CAACxB,CAAD,CAAWC,CAAX,CAFpB,QAEXwB,CAFW,iCAIVC,UAAUC,MAAV,CAAiB,qBAAjB,CAAwC,CAC3CF,MAAM,CAAEA,CADmC,CAE3CG,GAAG,CAAE1B,CAFsC,CAAxC,CAJU,0CAAH,uD,CAkBZsB,CAAgB,4CAAG,WAAMxB,CAAN,CAAgBC,CAAhB,yFACf4B,CADe,CACL,CACZC,UAAU,CAAE,iCADA,CAEZC,IAAI,CAAE,CACFC,aAAa,CAAEC,CAAC,CAACC,GAAF,CAAMC,SADnB,CAEFC,QAAQ,CAAEpC,CAFR,CAGFqC,UAAU,CAAEpC,CAHV,CAFM,CADK,0BAUdqC,UAAKC,IAAL,CAAU,CAACV,CAAD,CAAV,EAAqB,CAArB,CAVc,0CAAH,uD,QAqBF,QAAPW,CAAAA,IAAO,CAACxC,CAAD,CAAWC,CAAX,CAAuBC,CAAvB,CAAuC,CACvDH,CAAsB,CAACC,CAAD,CAAWC,CAAX,CAAuBC,CAAvB,CACzB,C","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 .\n\n/**\n * Show an add block modal instead of doing it on a separate page.\n *\n * @module core/addblockmodal\n * @class addblockmodal\n * @package core\n * @copyright 2016 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalFactory from 'core/modal_factory';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\nimport Ajax from 'core/ajax';\n\nconst SELECTORS = {\n ADD_BLOCK: '[data-key=\"addblock\"]'\n};\n\nlet addBlockModal = null;\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} addBlockUrl The add block URL\n */\nconst registerListenerEvents = (pageType, pageLayout, addBlockUrl) => {\n document.addEventListener('click', e => {\n\n if (e.target.closest(SELECTORS.ADD_BLOCK)) {\n e.preventDefault();\n\n if (addBlockModal) { // The 'add block' modal has been already created.\n // Display the 'add block' modal.\n addBlockModal.show();\n } else {\n buildAddBlockModal()\n .then(modal => {\n addBlockModal = modal;\n const modalBody = renderBlocks(addBlockUrl, pageType, pageLayout);\n modal.setBody(modalBody);\n modal.show();\n\n return modalBody;\n })\n .catch(() => {\n addBlockModal.destroy();\n // Unset the addBlockModal in case this is a transient error and it goes away on a relaunch.\n addBlockModal = null;\n });\n }\n }\n });\n};\n\n/**\n * Method that creates the 'add block' modal.\n *\n * @method buildAddBlockModal\n * @return {Promise} The modal promise (modal's body will be rendered later).\n */\nconst buildAddBlockModal = () => {\n return ModalFactory.create({\n type: ModalFactory.types.CANCEL,\n title: getString('addblock')\n });\n};\n\n/**\n * Method that renders the list of available blocks.\n *\n * @method renderBlocks\n * @param {String} addBlockUrl The add block URL\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @return {Promise}\n */\nconst renderBlocks = async(addBlockUrl, pageType, pageLayout) => {\n // Fetch all addable blocks in the given page.\n const blocks = await getAddableBlocks(pageType, pageLayout);\n\n return Templates.render('core/add_block_body', {\n blocks: blocks,\n url: addBlockUrl\n });\n};\n\n/**\n * Method that fetches all addable blocks in a given page.\n *\n * @method getAddableBlocks\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @return {Promise}\n */\nconst getAddableBlocks = async(pageType, pageLayout) => {\n const request = {\n methodname: 'core_block_fetch_addable_blocks',\n args: {\n pagecontextid: M.cfg.contextid,\n pagetype: pageType,\n pagelayout: pageLayout\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Set up the actions.\n *\n * @method init\n * @param {String} pageType The type of the page\n * @param {String} pageLayout The layout of the page\n * @param {String} addBlockUrl The add block URL\n */\nexport const init = (pageType, pageLayout, addBlockUrl) => {\n registerListenerEvents(pageType, pageLayout, addBlockUrl);\n};\n"],"file":"addblockmodal.min.js"} \ No newline at end of file diff --git a/lib/amd/src/addblockmodal.js b/lib/amd/src/addblockmodal.js index 5aed3236c57..03bd4c24ced 100644 --- a/lib/amd/src/addblockmodal.js +++ b/lib/amd/src/addblockmodal.js @@ -22,51 +22,116 @@ * @copyright 2016 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/modal_factory', 'core/templates', 'core/str', 'core/notification'], - function($, ModalFactory, Templates, Str, Notification) { +import ModalFactory from 'core/modal_factory'; +import Templates from 'core/templates'; +import {get_string as getString} from 'core/str'; +import Ajax from 'core/ajax'; - return /** @alias module:core/addblockmodal */ { - /** - * Global init function for this module. - * - * @method init - * @param {Object} context The template context for rendering this modal body. - */ - init: function(context) { - var addblocklink = $('[data-key=addblock]'); +const SELECTORS = { + ADD_BLOCK: '[data-key="addblock"]' +}; - // We need the fetch the names of the blocks. It was too much to send in the page. - var titlerequests = context.blocks.map(function(blockName) { - return { - key: 'pluginname', - component: 'block_' + blockName, - }; - }); +let addBlockModal = null; - var bodyPromise = Str.get_strings(titlerequests) - .then(function(titles) { - return titles.map(function(title, index) { - return { - name: context.blocks[index], - title: title, - }; +/** + * Register related event listeners. + * + * @method registerListenerEvents + * @param {String} pageType The type of the page + * @param {String} pageLayout The layout of the page + * @param {String} addBlockUrl The add block URL + */ +const registerListenerEvents = (pageType, pageLayout, addBlockUrl) => { + document.addEventListener('click', e => { + + if (e.target.closest(SELECTORS.ADD_BLOCK)) { + e.preventDefault(); + + if (addBlockModal) { // The 'add block' modal has been already created. + // Display the 'add block' modal. + addBlockModal.show(); + } else { + buildAddBlockModal() + .then(modal => { + addBlockModal = modal; + const modalBody = renderBlocks(addBlockUrl, pageType, pageLayout); + modal.setBody(modalBody); + modal.show(); + + return modalBody; + }) + .catch(() => { + addBlockModal.destroy(); + // Unset the addBlockModal in case this is a transient error and it goes away on a relaunch. + addBlockModal = null; }); - }) - .then(function(blocks) { - context.blocks = blocks; - return Templates.render('core/add_block_body', context); - }) - .fail(Notification.exception); - - var titlePromise = Str.get_string('addblock') - .fail(Notification.exception); - - ModalFactory.create({ - title: titlePromise, - body: bodyPromise, - type: 'CANCEL', - }, addblocklink); + } } + }); +}; + +/** + * Method that creates the 'add block' modal. + * + * @method buildAddBlockModal + * @return {Promise} The modal promise (modal's body will be rendered later). + */ +const buildAddBlockModal = () => { + return ModalFactory.create({ + type: ModalFactory.types.CANCEL, + title: getString('addblock') + }); +}; + +/** + * Method that renders the list of available blocks. + * + * @method renderBlocks + * @param {String} addBlockUrl The add block URL + * @param {String} pageType The type of the page + * @param {String} pageLayout The layout of the page + * @return {Promise} + */ +const renderBlocks = async(addBlockUrl, pageType, pageLayout) => { + // Fetch all addable blocks in the given page. + const blocks = await getAddableBlocks(pageType, pageLayout); + + return Templates.render('core/add_block_body', { + blocks: blocks, + url: addBlockUrl + }); +}; + +/** + * Method that fetches all addable blocks in a given page. + * + * @method getAddableBlocks + * @param {String} pageType The type of the page + * @param {String} pageLayout The layout of the page + * @return {Promise} + */ +const getAddableBlocks = async(pageType, pageLayout) => { + const request = { + methodname: 'core_block_fetch_addable_blocks', + args: { + pagecontextid: M.cfg.contextid, + pagetype: pageType, + pagelayout: pageLayout + }, }; -}); + + return Ajax.call([request])[0]; +}; + +/** + * Set up the actions. + * + * @method init + * @param {String} pageType The type of the page + * @param {String} pageLayout The layout of the page + * @param {String} addBlockUrl The add block URL + */ +export const init = (pageType, pageLayout, addBlockUrl) => { + registerListenerEvents(pageType, pageLayout, addBlockUrl); +}; diff --git a/lib/db/services.php b/lib/db/services.php index ef653f097c3..815404feace 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -2609,6 +2609,16 @@ $functions = array( 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'core_block_fetch_addable_blocks' => array( + 'classname' => 'core_block\external\fetch_addable_blocks', + 'methodname' => 'execute', + 'description' => 'Returns all addable blocks in a given page.', + 'type' => 'read', + 'capabilities' => 'moodle/site:manageblocks', + 'ajax' => true, + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + ), + // Filters functions. 'core_filters_get_available_in_context' => array( 'classname' => 'core_filters\external', diff --git a/lib/navigationlib.php b/lib/navigationlib.php index d579e8ef34a..1af265bd66d 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -4065,8 +4065,7 @@ class flat_navigation extends navigation_node_collection { // Add-a-block in editing mode. if (isset($this->page->theme->addblockposition) && $this->page->theme->addblockposition == BLOCK_ADDBLOCK_POSITION_FLATNAV && - $PAGE->user_is_editing() && $PAGE->user_can_edit_blocks() && - ($addable = $PAGE->blocks->get_addable_blocks())) { + $PAGE->user_is_editing() && $PAGE->user_can_edit_blocks()) { $url = new moodle_url($PAGE->url, ['bui_addblock' => '', 'sesskey' => sesskey()]); $addablock = navigation_node::create(get_string('addblock'), $url); $flat = new flat_navigation_node($addablock, 0); @@ -4074,12 +4073,11 @@ class flat_navigation extends navigation_node_collection { $flat->key = 'addblock'; $flat->icon = new pix_icon('i/addblock', ''); $this->add($flat); - $blocks = []; - foreach ($addable as $block) { - $blocks[] = $block->name; - } - $params = array('blocks' => $blocks, 'url' => '?' . $url->get_query_string(false)); - $PAGE->requires->js_call_amd('core/addblockmodal', 'init', array($params)); + + $addblockurl = "?{$url->get_query_string(false)}"; + + $PAGE->requires->js_call_amd('core/addblockmodal', 'init', + [$PAGE->pagetype, $PAGE->pagelayout, $addblockurl]); } } diff --git a/lib/templates/add_block_body.mustache b/lib/templates/add_block_body.mustache index 21dbe125c76..f6509511460 100644 --- a/lib/templates/add_block_body.mustache +++ b/lib/templates/add_block_body.mustache @@ -34,4 +34,9 @@ {{#blocks}} {{title}} {{/blocks}} +{{^blocks}} + +{{/blocks}} diff --git a/version.php b/version.php index ee4dc912e53..ab195f92b15 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2020112700.00; // 20201109 = branching date YYYYMMDD - do not modify! +$version = 2020112700.01; // 20201109 = branching date YYYYMMDD - do not modify! // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '3.11dev (Build: 20201127)';// Human-friendly version name