MDL-71913 mod_data: Add tertiary navigation

This commit is contained in:
Mihail Geshoski 2021-07-13 13:31:47 +08:00
parent 9145d80b0b
commit 6470282e93
39 changed files with 2192 additions and 667 deletions

View File

@ -0,0 +1,2 @@
define ("mod_data/saveaspreset",["exports","core_form/modalform","core/notification","core/str","core/toast"],function(a,b,c,d,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=f(b);c=f(c);function f(a){return a&&a.__esModule?a:{default:a}}var g={saveAsPresetButton:"[data-action=\"saveaspreset\"]"};a.init=function init(){var a=document.querySelector(g.saveAsPresetButton);a.addEventListener("click",function(f){f.preventDefault();var g=new b.default({modalConfig:{title:(0,d.get_string)("savedataaspreset","mod_data")},formClass:"mod_data\\form\\save_as_preset",args:{d:a.getAttribute("data-dataid")},saveButtonText:(0,d.get_string)("save"),returnFocus:a});g.addEventListener(g.events.FORM_SUBMITTED,function(a){if(a.detail.result){(0,d.get_string)("savesuccess","data").then(e.add).catch()}else{c.default.addNotification({type:"error",message:a.detail.errors.join("<br>")})}});g.show()})}});
//# sourceMappingURL=saveaspreset.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../src/saveaspreset.js"],"names":["selectors","saveAsPresetButton","init","document","querySelector","addEventListener","event","preventDefault","modalForm","ModalForm","modalConfig","title","formClass","args","d","getAttribute","saveButtonText","returnFocus","events","FORM_SUBMITTED","detail","result","then","addToast","catch","Notification","addNotification","type","message","errors","join","show"],"mappings":"8MAuBA,OACA,O,sDAIMA,CAAAA,CAAS,CAAG,CACdC,kBAAkB,CAAE,gCADN,C,QAOE,QAAPC,CAAAA,IAAO,EAAM,CACtB,GAAMD,CAAAA,CAAkB,CAAGE,QAAQ,CAACC,aAAT,CAAuBJ,CAAS,CAACC,kBAAjC,CAA3B,CAEAA,CAAkB,CAACI,gBAAnB,CAAoC,OAApC,CAA6C,SAAAC,CAAK,CAAI,CAClDA,CAAK,CAACC,cAAN,GAEA,GAAMC,CAAAA,CAAS,CAAG,GAAIC,UAAJ,CAAc,CAC5BC,WAAW,CAAE,CACTC,KAAK,CAAE,iBAAU,kBAAV,CAA8B,UAA9B,CADE,CADe,CAI5BC,SAAS,CAAE,gCAJiB,CAK5BC,IAAI,CAAE,CAACC,CAAC,CAAEb,CAAkB,CAACc,YAAnB,CAAgC,aAAhC,CAAJ,CALsB,CAM5BC,cAAc,CAAE,iBAAU,MAAV,CANY,CAO5BC,WAAW,CAAEhB,CAPe,CAAd,CAAlB,CAWAO,CAAS,CAACH,gBAAV,CAA2BG,CAAS,CAACU,MAAV,CAAiBC,cAA5C,CAA4D,SAAAb,CAAK,CAAI,CACjE,GAAIA,CAAK,CAACc,MAAN,CAAaC,MAAjB,CAAyB,CACrB,iBAAU,aAAV,CAAyB,MAAzB,EAAiCC,IAAjC,CAAsCC,KAAtC,EAAgDC,KAAhD,EACH,CAFD,IAEO,CACHC,UAAaC,eAAb,CAA6B,CACzBC,IAAI,CAAE,OADmB,CAEzBC,OAAO,CAAGtB,CAAK,CAACc,MAAN,CAAaS,MAAb,CAAoBC,IAApB,CAAyB,MAAzB,CAFe,CAA7B,CAIH,CACJ,CATD,EAWAtB,CAAS,CAACuB,IAAV,EACH,CA1BD,CA2BH,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 <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript module for saving a database as a preset.\n *\n * @module mod_data/saveaspreset\n * @copyright 2021 Mihail Geshoski <mihail@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalForm from 'core_form/modalform';\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\nimport {add as addToast} from 'core/toast';\n\nconst selectors = {\n saveAsPresetButton: '[data-action=\"saveaspreset\"]',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n const saveAsPresetButton = document.querySelector(selectors.saveAsPresetButton);\n\n saveAsPresetButton.addEventListener('click', event => {\n event.preventDefault();\n\n const modalForm = new ModalForm({\n modalConfig: {\n title: getString('savedataaspreset', 'mod_data'),\n },\n formClass: 'mod_data\\\\form\\\\save_as_preset',\n args: {d: saveAsPresetButton.getAttribute('data-dataid')},\n saveButtonText: getString('save'),\n returnFocus: saveAsPresetButton,\n });\n\n // Show a toast notification when the form is submitted.\n modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {\n if (event.detail.result) {\n getString('savesuccess', 'data').then(addToast).catch();\n } else {\n Notification.addNotification({\n type: 'error',\n message: event.detail.errors.join('<br>')\n });\n }\n });\n\n modalForm.show();\n });\n};\n"],"file":"saveaspreset.min.js"}

View File

@ -0,0 +1,2 @@
define ("mod_data/selectpreset",["exports","core/notification","core/str"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var d={selectPresetButton:"input[name=\"selectpreset\"]",selectedPresetRadioButton:"input[name=\"fullname\"]:checked"};a.init=function init(){var a=document.querySelector(d.selectPresetButton);a.addEventListener("click",function(a){a.preventDefault();if(0<document.querySelectorAll(d.selectedPresetRadioButton).length){var e=a.target.closest("form");e.submit()}else{(0,c.get_string)("presetnotselected","mod_data").then(function(a){return b.default.addNotification({type:"error",message:a})}).catch(b.default.exception)}})}});
//# sourceMappingURL=selectpreset.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../src/selectpreset.js"],"names":["selectors","selectPresetButton","selectedPresetRadioButton","init","document","querySelector","addEventListener","event","preventDefault","querySelectorAll","length","presetsForm","target","closest","submit","then","str","Notification","addNotification","type","message","catch","exception"],"mappings":"uKAuBA,uD,GAGMA,CAAAA,CAAS,CAAG,CACdC,kBAAkB,CAAE,8BADN,CAEdC,yBAAyB,CAAE,kCAFb,C,QAQE,QAAPC,CAAAA,IAAO,EAAM,CACtB,GAAMF,CAAAA,CAAkB,CAAGG,QAAQ,CAACC,aAAT,CAAuBL,CAAS,CAACC,kBAAjC,CAA3B,CAEAA,CAAkB,CAACK,gBAAnB,CAAoC,OAApC,CAA6C,SAAAC,CAAK,CAAI,CAClDA,CAAK,CAACC,cAAN,GAEA,GAA4E,CAAxE,CAAAJ,QAAQ,CAACK,gBAAT,CAA0BT,CAAS,CAACE,yBAApC,EAA+DQ,MAAnE,CAA+E,CAC3E,GAAMC,CAAAA,CAAW,CAAGJ,CAAK,CAACK,MAAN,CAAaC,OAAb,CAAqB,MAArB,CAApB,CACAF,CAAW,CAACG,MAAZ,EACH,CAHD,IAGO,CAEH,iBAAU,mBAAV,CAA+B,UAA/B,EAA2CC,IAA3C,CAAgD,SAACC,CAAD,CAAS,CACrD,MAAOC,WAAaC,eAAb,CAA6B,CAChCC,IAAI,CAAE,OAD0B,CAEhCC,OAAO,CAAEJ,CAFuB,CAA7B,CAIV,CALD,EAKGK,KALH,CAKSJ,UAAaK,SALtB,CAMH,CACJ,CAfD,CAgBH,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 <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript module to control the form responsible for selecting a preset.\n *\n * @module mod_data/selectpreset\n * @copyright 2021 Mihail Geshoski <mihail@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Notification from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nconst selectors = {\n selectPresetButton: 'input[name=\"selectpreset\"]',\n selectedPresetRadioButton: 'input[name=\"fullname\"]:checked',\n};\n\n/**\n * Initialize module.\n */\nexport const init = () => {\n const selectPresetButton = document.querySelector(selectors.selectPresetButton);\n\n selectPresetButton.addEventListener('click', event => {\n event.preventDefault();\n // Validate whether there is a selected preset before submitting the form.\n if (document.querySelectorAll(selectors.selectedPresetRadioButton).length > 0) {\n const presetsForm = event.target.closest('form');\n presetsForm.submit();\n } else {\n // No selected presets. Display an error message to user.\n getString('presetnotselected', 'mod_data').then((str) => {\n return Notification.addNotification({\n type: 'error',\n message: str\n });\n }).catch(Notification.exception);\n }\n });\n};\n"],"file":"selectpreset.min.js"}

View File

@ -0,0 +1,2 @@
define ("mod_data/templateseditor",["exports","core/str","core/notification","core/url"],function(a,b,c,e){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;function f(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 g(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function g(a){f(i,d,e,g,h,"next",a)}function h(a){f(i,d,e,g,h,"throw",a)}g(void 0)})}}var h={toggleTemplateEditor:"input[name=\"useeditor\"]"},i=function(a,d){var f=document.querySelector(h.toggleTemplateEditor);f.addEventListener("click",function(){var f=g(regeneratorRuntime.mark(function f(g){var h;return regeneratorRuntime.wrap(function(f){while(1){switch(f.prev=f.next){case 0:g.preventDefault();h=g.target.checked;if(h){(0,c.confirm)((0,b.get_string)("confirmation","admin"),(0,b.get_string)("enabletemplateeditorcheck","mod_data"),(0,b.get_string)("yes","core"),(0,b.get_string)("no","core"),function(){window.location=(0,e.relativeUrl)("/mod/data/templates.php",{d:a,mode:d,useeditor:!0})})}else{window.location=(0,e.relativeUrl)("/mod/data/templates.php",{d:a,mode:d,useeditor:!1})}case 3:case"end":return f.stop();}}},f)}));return function(){return f.apply(this,arguments)}}())};a.init=function init(a,b){i(a,b)}});
//# sourceMappingURL=templateseditor.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../src/templateseditor.js"],"names":["selectors","toggleTemplateEditor","registerEventListeners","d","mode","document","querySelector","addEventListener","event","preventDefault","enableTemplateEditor","target","checked","window","location","useeditor","init"],"mappings":"yfA8BMA,CAAAA,CAAS,CAAG,CACdC,oBAAoB,CAAE,2BADR,C,CAUZC,CAAsB,CAAG,SAACC,CAAD,CAAIC,CAAJ,CAAa,CACxC,GAAMH,CAAAA,CAAoB,CAAGI,QAAQ,CAACC,aAAT,CAAuBN,CAAS,CAACC,oBAAjC,CAA7B,CAEAA,CAAoB,CAACM,gBAArB,CAAsC,OAAtC,4CAA+C,WAAMC,CAAN,yFAC3CA,CAAK,CAACC,cAAN,GAEMC,CAHqC,CAGdF,CAAK,CAACG,MAAN,CAAaC,OAHC,CAK3C,GAAIF,CAAJ,CAA0B,CAEtB,cACI,iBAAU,cAAV,CAA0B,OAA1B,CADJ,CAEI,iBAAU,2BAAV,CAAuC,UAAvC,CAFJ,CAGI,iBAAU,KAAV,CAAiB,MAAjB,CAHJ,CAII,iBAAU,IAAV,CAAgB,MAAhB,CAJJ,CAKI,UAAM,CACFG,MAAM,CAACC,QAAP,CAAkB,kBAAY,yBAAZ,CAAuC,CAACX,CAAC,CAAEA,CAAJ,CAAOC,IAAI,CAAEA,CAAb,CAAmBW,SAAS,GAA5B,CAAvC,CACrB,CAPL,CASH,CAXD,IAWO,CACHF,MAAM,CAACC,QAAP,CAAkB,kBAAY,yBAAZ,CAAuC,CAACX,CAAC,CAAEA,CAAJ,CAAOC,IAAI,CAAEA,CAAb,CAAmBW,SAAS,GAA5B,CAAvC,CACrB,CAlB0C,wCAA/C,wDAoBH,C,QAQmB,QAAPC,CAAAA,IAAO,CAACb,CAAD,CAAIC,CAAJ,CAAa,CAC7BF,CAAsB,CAACC,CAAD,CAAIC,CAAJ,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 <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript module to control the template editor.\n *\n * @module mod_data/templateseditor\n * @copyright 2021 Mihail Geshoski <mihail@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {get_string as getString} from 'core/str';\nimport {confirm as confirmDialogue} from 'core/notification';\nimport {relativeUrl} from 'core/url';\n\n/**\n * Template editor constants.\n */\nconst selectors = {\n toggleTemplateEditor: 'input[name=\"useeditor\"]',\n};\n\n/**\n * Register event listeners for the module.\n *\n * @param {int} d The database ID\n * @param {string} mode The template mode\n */\nconst registerEventListeners = (d, mode) => {\n const toggleTemplateEditor = document.querySelector(selectors.toggleTemplateEditor);\n\n toggleTemplateEditor.addEventListener('click', async(event) => {\n event.preventDefault();\n // Whether the event action attempts to enable or disable the template editor.\n const enableTemplateEditor = event.target.checked;\n\n if (enableTemplateEditor) {\n // Display a confirmation dialog before enabling the template editor.\n confirmDialogue(\n getString('confirmation', 'admin'),\n getString('enabletemplateeditorcheck', 'mod_data'),\n getString('yes', 'core'),\n getString('no', 'core'),\n () => {\n window.location = relativeUrl('/mod/data/templates.php', {d: d, mode: mode, useeditor: true});\n }\n );\n } else {\n window.location = relativeUrl('/mod/data/templates.php', {d: d, mode: mode, useeditor: false});\n }\n });\n};\n\n/**\n * Initialize the module.\n *\n * @param {int} d The database ID\n * @param {string} mode The template mode\n */\nexport const init = (d, mode) => {\n registerEventListeners(d, mode);\n};\n"],"file":"templateseditor.min.js"}

View File

@ -0,0 +1,66 @@
// 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/>.
/**
* Javascript module for saving a database as a preset.
*
* @module mod_data/saveaspreset
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalForm from 'core_form/modalform';
import Notification from 'core/notification';
import {get_string as getString} from 'core/str';
import {add as addToast} from 'core/toast';
const selectors = {
saveAsPresetButton: '[data-action="saveaspreset"]',
};
/**
* Initialize module
*/
export const init = () => {
const saveAsPresetButton = document.querySelector(selectors.saveAsPresetButton);
saveAsPresetButton.addEventListener('click', event => {
event.preventDefault();
const modalForm = new ModalForm({
modalConfig: {
title: getString('savedataaspreset', 'mod_data'),
},
formClass: 'mod_data\\form\\save_as_preset',
args: {d: saveAsPresetButton.getAttribute('data-dataid')},
saveButtonText: getString('save'),
returnFocus: saveAsPresetButton,
});
// Show a toast notification when the form is submitted.
modalForm.addEventListener(modalForm.events.FORM_SUBMITTED, event => {
if (event.detail.result) {
getString('savesuccess', 'data').then(addToast).catch();
} else {
Notification.addNotification({
type: 'error',
message: event.detail.errors.join('<br>')
});
}
});
modalForm.show();
});
};

View File

@ -0,0 +1,54 @@
// 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/>.
/**
* Javascript module to control the form responsible for selecting a preset.
*
* @module mod_data/selectpreset
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Notification from 'core/notification';
import {get_string as getString} from 'core/str';
const selectors = {
selectPresetButton: 'input[name="selectpreset"]',
selectedPresetRadioButton: 'input[name="fullname"]:checked',
};
/**
* Initialize module.
*/
export const init = () => {
const selectPresetButton = document.querySelector(selectors.selectPresetButton);
selectPresetButton.addEventListener('click', event => {
event.preventDefault();
// Validate whether there is a selected preset before submitting the form.
if (document.querySelectorAll(selectors.selectedPresetRadioButton).length > 0) {
const presetsForm = event.target.closest('form');
presetsForm.submit();
} else {
// No selected presets. Display an error message to user.
getString('presetnotselected', 'mod_data').then((str) => {
return Notification.addNotification({
type: 'error',
message: str
});
}).catch(Notification.exception);
}
});
};

View File

@ -0,0 +1,74 @@
// 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/>.
/**
* Javascript module to control the template editor.
*
* @module mod_data/templateseditor
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {get_string as getString} from 'core/str';
import {confirm as confirmDialogue} from 'core/notification';
import {relativeUrl} from 'core/url';
/**
* Template editor constants.
*/
const selectors = {
toggleTemplateEditor: 'input[name="useeditor"]',
};
/**
* Register event listeners for the module.
*
* @param {int} d The database ID
* @param {string} mode The template mode
*/
const registerEventListeners = (d, mode) => {
const toggleTemplateEditor = document.querySelector(selectors.toggleTemplateEditor);
toggleTemplateEditor.addEventListener('click', async(event) => {
event.preventDefault();
// Whether the event action attempts to enable or disable the template editor.
const enableTemplateEditor = event.target.checked;
if (enableTemplateEditor) {
// Display a confirmation dialog before enabling the template editor.
confirmDialogue(
getString('confirmation', 'admin'),
getString('enabletemplateeditorcheck', 'mod_data'),
getString('yes', 'core'),
getString('no', 'core'),
() => {
window.location = relativeUrl('/mod/data/templates.php', {d: d, mode: mode, useeditor: true});
}
);
} else {
window.location = relativeUrl('/mod/data/templates.php', {d: d, mode: mode, useeditor: false});
}
});
};
/**
* Initialize the module.
*
* @param {int} d The database ID
* @param {string} mode The template mode
*/
export const init = (d, mode) => {
registerEventListeners(d, mode);
};

View File

@ -0,0 +1,186 @@
<?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 mod_data\form;
use context;
use moodle_exception;
use moodle_url;
use core_form\dynamic_form;
/**
* Save database as preset form.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class save_as_preset extends dynamic_form {
/**
* Form definition
*/
protected function definition() {
$this->_form->addElement('hidden', 'd');
$this->_form->setType('d', PARAM_INT);
$this->_form->addElement('hidden', 'action', 'save2');
$this->_form->setType('action', PARAM_ALPHANUM);
$this->_form->addElement('text', 'name', get_string('name'), ['size' => 60]);
$this->_form->setType('name', PARAM_FILE);
$this->_form->addRule('name', null, 'required');
$this->_form->addElement('checkbox', 'overwrite', '', get_string('overrwritedesc', 'data'));
}
/**
* Return form context
*
* @return context
*/
protected function get_context_for_dynamic_submission(): context {
global $DB;
$d = $this->optional_param('d', null, PARAM_INT);
$data = $DB->get_record('data', array('id' => $d), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $data->course), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
return \context_module::instance($cm->id, MUST_EXIST);
}
/**
* Perform some validation.
*
* @param array $formdata
* @param array $files
* @return array
*/
public function validation($formdata, $files): array {
$errors = parent::validation($formdata, $files);
$context = $this->get_context_for_dynamic_submission();
if (!empty($formdata['overwrite'])) {
$presets = data_get_available_presets($context);
$selectedpreset = new \stdClass();
foreach ($presets as $preset) {
if ($preset->name == $formdata['name']) {
$selectedpreset = $preset;
break;
}
}
if (isset($selectedpreset->name) && !data_user_can_delete_preset($context, $selectedpreset)) {
$errors['name'] = get_string('cannotoverwritepreset', 'data');
}
} else {
// If the preset exists now then we need to throw an error.
$sitepresets = data_get_available_site_presets($context);
foreach ($sitepresets as $preset) {
if ($formdata['name'] == $preset->name) {
$errors['name'] = get_string('errorpresetexists', 'data');
}
}
}
return $errors;
}
/**
* Check if current user has access to this form, otherwise throw exception.
*
* @return void
* @throws moodle_exception
*/
protected function check_access_for_dynamic_submission(): void {
global $DB;
if (!has_capability('mod/data:managetemplates', $this->get_context_for_dynamic_submission())) {
throw new moodle_exception('saveaspresetmissingcapability', 'data');
}
$d = $this->optional_param('d', null, PARAM_INT);
$hasfields = $DB->record_exists('data_fields', ['dataid' => $d]);
if (!$hasfields) {
throw new moodle_exception('nofieldindatabase', 'data');
}
}
/**
* Process the form submission, used if form was submitted via AJAX.
*
* @return array
*/
public function process_dynamic_submission(): array {
global $DB, $CFG;
require_once($CFG->dirroot . '/mod/data/lib.php');
$result = false;
$errors = [];
$data = $DB->get_record('data', array('id' => $this->get_data()->d), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $data->course), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
$context = \context_module::instance($cm->id, MUST_EXIST);
try {
if (!empty($this->get_data()->overwrite)) {
$presets = data_get_available_presets($context);
$selectedpreset = new \stdClass();
foreach ($presets as $preset) {
if ($preset->name == $this->get_data()->name) {
$selectedpreset = $preset;
break;
}
}
if (isset($selectedpreset->name) && data_user_can_delete_preset($context, $selectedpreset)) {
data_delete_site_preset($this->get_data()->name);
}
}
data_presets_save($course, $cm, $data, $this->get_data()->name);
$result = true;
} catch (\Exception $e) {
$errors[] = $e->getMessage();
}
return [
'result' => $result,
'errors' => $errors,
];
}
/**
* Load in existing data as form defaults.
*
* @return void
*/
public function set_data_for_dynamic_submission(): void {
$data = (object)[
'd' => $this->optional_param('d', 0, PARAM_INT),
];
$this->set_data($data);
}
/**
* Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
*
* @return moodle_url
*/
protected function get_page_url_for_dynamic_submission(): moodle_url {
$d = $this->optional_param('d', null, PARAM_INT);
return new moodle_url('/user/field.php', ['d' => $d]);
}
}

View File

@ -0,0 +1,220 @@
<?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 mod_data\output;
use moodle_url;
/**
* Class responsible for generating the action bar elements in the database module pages.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class action_bar {
/** @var int $id The database module id. */
private $id;
/** @var moodle_url $currenturl The URL of the current page. */
private $currenturl;
/**
* The class constructor.
*
* @param int $id The database module id.
* @param moodle_url $pageurl The URL of the current page.
*/
public function __construct(int $id, moodle_url $pageurl) {
$this->id = $id;
$this->currenturl = $pageurl;
}
/**
* Generate the output for the action bar in the field page.
*
* @param bool $hasfieldselect Whether the field selector element should be rendered.
* @param bool $hassaveaspreset Whether the save as preset button element should be rendered.
* @param bool $hasexportpreset Whether the export as preset button element should be rendered.
* @return string The HTML code for the action bar.
*/
public function get_fields_action_bar(bool $hasfieldselect = false, bool $hassaveaspreset = false,
bool $hasexportpreset = false): string {
global $PAGE, $DB;
$createfieldlink = new moodle_url('/mod/data/field.php', ['d' => $this->id]);
$importlink = new moodle_url('/mod/data/field.php', ['d' => $this->id, 'mode' => 'import']);
$presetslink = new moodle_url('/mod/data/field.php', ['d' => $this->id, 'mode' => 'usepreset']);
$menu = [
$createfieldlink->out(false) => get_string('newfield', 'mod_data'),
$importlink->out(false) => get_string('importpreset', 'mod_data'),
$presetslink->out(false) => get_string('usestandard', 'mod_data'),
];
$selected = $createfieldlink->out(false);
$mode = $this->currenturl->get_param('mode');
if ($mode == 'import') {
$selected = $importlink->out(false);
} else if ($mode === 'usepreset') {
$selected = $presetslink->out(false);
}
$urlselect = new \url_select($menu, $selected, null, 'fieldactionselect');
$fieldselect = null;
if ($hasfieldselect) {
// Get the list of possible fields (plugins).
$plugins = \core_component::get_plugin_list('datafield');
$menufield = [];
foreach ($plugins as $plugin => $fulldir) {
$menufield[$plugin] = get_string('pluginname', "datafield_{$plugin}");
}
asort($menufield);
$fieldselecturl = new moodle_url('/mod/data/field.php', ['d' => $this->id, 'mode' => 'new']);
$fieldselect = new \single_select($fieldselecturl, 'newtype', $menufield, null, ['' => 'choosedots'],
'fieldform');
}
$saveaspresetbutton = null;
$exportpresetbutton = null;
$hasfields = $DB->record_exists('data_fields', ['dataid' => $this->id]);
if ($hasfields) {
if ($hassaveaspreset) {
$saveaspresetlink = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'action' => 'export']);
$saveaspresetbutton = new \single_button($saveaspresetlink,
get_string('saveaspreset', 'mod_data'), 'post', false);
}
if ($hasexportpreset) {
$exportpresetlink = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'action' => 'export']);
$exportpresetbutton = new \single_button($exportpresetlink,
get_string('exportpreset', 'mod_data'), 'get', false);
}
}
$renderer = $PAGE->get_renderer('mod_data');
$fieldsactionbar = new fields_action_bar($this->id, $urlselect, $fieldselect, $saveaspresetbutton,
$exportpresetbutton);
return $renderer->render_fields_action_bar($fieldsactionbar);
}
/**
* Generate the output for the action selector in the view page.
*
* @param bool $hasentries Whether entries exist
* @return string The HTML code for the action selector.
*/
public function get_view_action_bar(bool $hasentries): string {
global $PAGE;
$viewlistlink = new moodle_url('/mod/data/view.php', ['d' => $this->id]);
$viewsinglelink = new moodle_url('/mod/data/view.php', ['d' => $this->id, 'mode' => 'single']);
$menu = [
$viewlistlink->out(false) => get_string('listview', 'mod_data'),
$viewsinglelink->out(false) => get_string('singleview', 'mod_data'),
];
$activeurl = $this->currenturl;
if ($this->currenturl->get_param('rid') || $this->currenturl->get_param('mode') == 'single') {
$activeurl = $viewsinglelink;
}
$urlselect = new \url_select($menu, $activeurl->out(false), null, 'viewactionselect');
$renderer = $PAGE->get_renderer('mod_data');
$viewactionbar = new view_action_bar($this->id, $urlselect, $hasentries);
return $renderer->render_view_action_bar($viewactionbar);
}
/**
* Generate the output for the action selector in the templates page.
*
* @return string The HTML code for the action selector.
*/
public function get_templates_action_bar(): string {
global $PAGE, $DB;
$listtemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id,
'mode' => 'listtemplate']);
$singletemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id,
'mode' => 'singletemplate']);
$advancedsearchtemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id,
'mode' => 'asearchtemplate']);
$addtemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id, 'mode' => 'addtemplate']);
$rsstemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id, 'mode' => 'rsstemplate']);
$csstemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id, 'mode' => 'csstemplate']);
$jstemplatelink = new moodle_url('/mod/data/templates.php', ['d' => $this->id, 'mode' => 'jstemplate']);
$menu = [
$listtemplatelink->out(false) => get_string('listtemplate', 'mod_data'),
$singletemplatelink->out(false) => get_string('singletemplate', 'mod_data'),
$advancedsearchtemplatelink->out(false) => get_string('asearchtemplate', 'mod_data'),
$addtemplatelink->out(false) => get_string('addtemplate', 'mod_data'),
$rsstemplatelink->out(false) => get_string('rsstemplate', 'mod_data'),
$csstemplatelink->out(false) => get_string('csstemplate', 'mod_data'),
$jstemplatelink->out(false) => get_string('jstemplate', 'mod_data'),
];
$urlselect = new \url_select($menu, $this->currenturl->out(false), null, 'templatesactionselect');
$hasfields = $DB->record_exists('data_fields', ['dataid' => $this->id]);
$saveaspresetbutton = null;
$exportpresetbutton = null;
if ($hasfields) {
$saveaspresetlink = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'action' => 'export']);
$saveaspresetbutton = new \single_button($saveaspresetlink,
get_string('saveaspreset', 'mod_data'), 'post', false);
$exportpresetlink = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'action' => 'export', 'sesskey' => sesskey()]);
$exportpresetbutton = new \single_button($exportpresetlink,
get_string('exportpreset', 'mod_data'), 'get', false);
}
$renderer = $PAGE->get_renderer('mod_data');
$templatesactionbar = new templates_action_bar($this->id, $urlselect, $saveaspresetbutton,
$exportpresetbutton);
return $renderer->render_templates_action_bar($templatesactionbar);
}
/**
* Generate the output for the action selector in the presets page.
*
* @return string The HTML code for the action selector.
*/
public function get_presets_action_bar(): string {
global $PAGE;
$renderer = $PAGE->get_renderer('mod_data');
$presetsactionbar = new presets_action_bar($this->id);
return $renderer->render_presets_action_bar($presetsactionbar);
}
}

View File

@ -0,0 +1,89 @@
<?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 mod_data\output;
use templatable;
use renderable;
/**
* Renderable class for the action bar elements in the field pages in the database activity.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class fields_action_bar implements templatable, renderable {
/** @var int $id The database module id. */
private $id;
/** @var \url_select $urlselect The URL selector object. */
private $urlselect;
/** @var \single_select|null $fieldselect The field selector object or null. */
private $fieldselect;
/** @var \single_button|null $saveaspresetbutton The save as preset single button object or null. */
private $saveaspresetbutton;
/** @var \single_button|null $exportpresetbutton The export preset single button object or null. */
private $exportpresetbutton;
/**
* The class constructor.
*
* @param int $id The database module id
* @param \url_select $urlselect The URL selector object
* @param \single_select|null $fieldselect The field selector object or null
* @param \single_button|null $saveaspresetbutton The save as preset single button object or null
* @param \single_button|null $exportpresetbutton The export preset single button object or null
*/
public function __construct(int $id, \url_select $urlselect, ?\single_select $fieldselect = null,
?\single_button $saveaspresetbutton = null, ?\single_button $exportpresetbutton = null) {
$this->id = $id;
$this->urlselect = $urlselect;
$this->fieldselect = $fieldselect;
$this->saveaspresetbutton = $saveaspresetbutton;
$this->exportpresetbutton = $exportpresetbutton;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output The renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$data = [
'd' => $this->id,
'urlselect' => $this->urlselect->export_for_template($output),
];
if ($this->fieldselect) {
$data['fieldselect'] = $this->fieldselect->export_for_template($output);
}
$data['saveaspreset'] = $this->saveaspresetbutton;
if ($this->exportpresetbutton) {
$data['exportpreset'] = $this->exportpresetbutton->export_for_template($output);
}
return $data;
}
}

View File

@ -0,0 +1,117 @@
<?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 mod_data\output;
use moodle_url;
use templatable;
use renderable;
/**
* Renderable class for the presets table in the database activity.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class presets implements templatable, renderable {
/** @var int $id The database module id. */
private $id;
/** @var array $presets The array containing the existing presets. */
private $presets;
/** @var moodle_url $formactionurl The the action url for the form. */
private $formactionurl;
/** @var bool $manage Whether the manage preset options should be displayed. */
private $manage;
/**
* The class constructor.
*
* @param int $id The database module id
* @param array $presets The array containing the existing presets
* @param moodle_url $formactionurl The the action url for the form
* @param bool $manage Whether the manage preset options should be displayed
*/
public function __construct(int $id, array $presets, moodle_url $formactionurl, bool $manage = false) {
$this->id = $id;
$this->presets = $presets;
$this->formactionurl = $formactionurl;
$this->manage = $manage;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output The renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
return [
'd' => $this->id,
'formactionul' => $this->formactionurl->out(),
'presetstable' => $this->get_presets_table(),
];
}
/**
* Generates and returns the HTML for the presets table.
*
* @return string
*/
private function get_presets_table(): string {
global $OUTPUT, $PAGE, $DB;
$presetstable = new \html_table();
$presetstable->align = ['center', 'left', 'left'];
$presetstable->size = ['1%', '90%', '1%'];
foreach ($this->presets as $preset) {
$presetname = $preset->name;
if (!empty($preset->userid)) {
$userfieldsapi = \core_user\fields::for_name();
$namefields = $userfieldsapi->get_sql('', false, '', '', false)->selects;
$presetuser = $DB->get_record('user', array('id' => $preset->userid), 'id, ' . $namefields, MUST_EXIST);
$username = fullname($presetuser, true);
$presetname = "{$presetname} ({$username})";
}
$deleteaction = '';
if ($this->manage) {
if (data_user_can_delete_preset($PAGE->context, $preset) && $preset->name != 'Image gallery') {
$deleteactionurl = new moodle_url('/mod/data/preset.php',
['d' => $this->id, 'fullname' => "{$preset->userid}/{$preset->shortname}",
'action' => 'confirmdelete']);
$deleteaction = $OUTPUT->action_icon($deleteactionurl,
new \pix_icon('t/delete', get_string('delete')));
}
}
$presetstable->data[] = [
\html_writer::tag('input', '', array('type' => 'radio', 'name' => 'fullname',
'value' => "{$preset->userid}/{$preset->shortname}")),
$presetname,
$deleteaction,
];
}
return \html_writer::table($presetstable);
}
}

View File

@ -0,0 +1,57 @@
<?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 mod_data\output;
use moodle_url;
use templatable;
use renderable;
/**
* Renderable class for the action bar elements in the presets page in the database activity.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class presets_action_bar implements templatable, renderable {
/** @var int $id The database module id. */
private $id;
/**
* The class constructor.
*
* @param int $id The database module id
*/
public function __construct(int $id) {
$this->id = $id;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output The renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$importpresetlink = new moodle_url('/mod/data/preset.php', ['d' => $this->id, 'action' => 'import']);
return [
'importpreseturl' => $importpresetlink->out(false),
];
}
}

View File

@ -0,0 +1,80 @@
<?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 mod_data\output;
use templatable;
use renderable;
/**
* Renderable class for the action bar elements in the template pages in the database activity.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class templates_action_bar implements templatable, renderable {
/** @var int $id The database module id. */
private $id;
/** @var \url_select $urlselect The URL selector object. */
private $urlselect;
/** @var \single_button|null $urlselect The save as preset single button object. */
private $saveaspresetbutton;
/** @var \single_button|null $urlselect The export preset single button object. */
private $exportpresetbutton;
/**
* The class constructor.
*
* @param int $id The database module id.
* @param \url_select $urlselect The URL selector object.
* @param \single_button|null $saveaspresetbutton The save as preset single button object or null.
* @param \single_button|null $exportpresetbutton The export preset single button object or null.
*/
public function __construct(int $id, \url_select $urlselect, ?\single_button $saveaspresetbutton,
?\single_button $exportpresetbutton) {
$this->id = $id;
$this->urlselect = $urlselect;
$this->saveaspresetbutton = $saveaspresetbutton;
$this->exportpresetbutton = $exportpresetbutton;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
$data = [
'd' => $this->id,
'urlselect' => $this->urlselect->export_for_template($output),
];
$data['saveaspreset'] = $this->saveaspresetbutton;
if ($this->exportpresetbutton) {
$data['exportpreset'] = $this->exportpresetbutton->export_for_template($output);
}
return $data;
}
}

View File

@ -0,0 +1,91 @@
<?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 mod_data\output;
use moodle_url;
use templatable;
use renderable;
/**
* Renderable class for the action bar elements in the view pages in the database activity.
*
* @package mod_data
* @copyright 2021 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_action_bar implements templatable, renderable {
/** @var int $id The database module id. */
private $id;
/** @var \url_select $urlselect The URL selector object. */
private $urlselect;
/** @var bool $hasentries Whether entries exist. */
private $hasentries;
/**
* The class constructor.
*
* @param int $id The database module id.
* @param \url_select $urlselect The URL selector object.
* @param bool $hasentries Whether entries exist.
*/
public function __construct(int $id, \url_select $urlselect, bool $hasentries) {
$this->id = $id;
$this->urlselect = $urlselect;
$this->hasentries = $hasentries;
}
/**
* Export the data for the mustache template.
*
* @param \renderer_base $output The renderer to be used to render the action bar elements.
* @return array
*/
public function export_for_template(\renderer_base $output): array {
global $PAGE;
$addentrylink = new moodle_url('/mod/data/edit.php',
['d' => $this->id, 'backto' => $PAGE->url->out(false)]);
$addentrybutton = new \single_button($addentrylink, get_string('add', 'mod_data'),
'get', true);
$data = [
'urlselect' => $this->urlselect->export_for_template($output),
'addentrybutton' => $addentrybutton->export_for_template($output),
];
if (has_capability('mod/data:manageentries', $PAGE->context)) {
$importentrieslink = new moodle_url('/mod/data/import.php',
['d' => $this->id, 'backto' => $PAGE->url->out(false)]);
$importentriesbutton = new \single_button($importentrieslink,
get_string('importentries', 'mod_data'), 'get', false);
$data['importentriesbutton'] = $importentriesbutton->export_for_template($output);
}
if (has_capability(DATA_CAP_EXPORT, $PAGE->context) && $this->hasentries) {
$exportentrieslink = new moodle_url('/mod/data/export.php',
['d' => $this->id, 'backto' => $PAGE->url->out(false)]);
$exportentriesbutton = new \single_button($exportentrieslink, get_string('exportentries', 'mod_data'),
'get', false);
$data['exportentriesbutton'] = $exportentriesbutton->export_for_template($output);
}
return $data;
}
}

View File

@ -31,9 +31,9 @@ require_once("$CFG->libdir/form/filemanager.php");
$id = optional_param('id', 0, PARAM_INT); // course module id
$d = optional_param('d', 0, PARAM_INT); // database id
$rid = optional_param('rid', 0, PARAM_INT); //record id
$cancel = optional_param('cancel', '', PARAM_RAW); // cancel an add
$mode ='addtemplate'; //define the mode for this page, only 1 mode available
$tags = optional_param_array('tags', [], PARAM_TAGLIST);
$redirectbackto = optional_param('backto', '', PARAM_LOCALURL); // The location to redirect back.
$url = new moodle_url('/mod/data/edit.php');
if ($rid !== 0) {
@ -43,9 +43,6 @@ if ($rid !== 0) {
), '*', MUST_EXIST);
$url->param('rid', $rid);
}
if ($cancel !== '') {
$url->param('cancel', $cancel);
}
if ($id) {
$url->param('id', $id);
@ -74,6 +71,8 @@ if ($id) {
}
}
$url->param('backto', $redirectbackto);
require_login($course, false, $cm);
if (isguestuser()) {
@ -120,11 +119,6 @@ if (!has_capability('mod/data:manageentries', $context)) {
}
}
if ($cancel) {
redirect('view.php?d='.$data->id);
}
/// RSS and CSS and JS meta
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
@ -157,6 +151,7 @@ if ($rid) {
$PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
$PAGE->set_secondary_active_tab('modulepage');
// Process incoming data for adding/updating records.
@ -231,7 +226,10 @@ if ($datarecord = data_submitted() and confirm_sesskey()) {
/// Print the page header
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($data->name), 2);
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
}
// Render the activity information.
$cminfo = cm_info::create($cm);
@ -242,15 +240,6 @@ echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
groups_print_activity_menu($cm, $CFG->wwwroot.'/mod/data/edit.php?d='.$data->id);
/// Print the tabs
$currenttab = 'add';
if ($rid) {
$editentry = true; //used in tabs
}
include('tabs.php');
/// Print the browsing interface
$patterns = array(); //tags to replace
@ -315,20 +304,20 @@ foreach ($generalnotifications as $notification) {
}
echo $newtext;
echo '<div class="mdl-align mt-1"><input type="submit" class="btn btn-primary" name="saveandview" ' .
'value="' . get_string('saveandview', 'data') . '" />';
if ($rid) {
echo '&nbsp;<input type="submit" class="btn btn-primary" name="cancel" ' .
'value="' . get_string('cancel') . '" onclick="javascript:history.go(-1)" />';
} else {
if ((!$data->maxentries) ||
has_capability('mod/data:manageentries', $context) ||
(data_numentries($data) < ($data->maxentries - 1))) {
echo '&nbsp;<input type="submit" class="btn btn-primary" name="saveandadd" ' .
'value="' . get_string('saveandadd', 'data') . '" />';
}
$redirectbackto = !empty($redirectbackto) ? $redirectbackto :
new \moodle_url('/mod/data/view.php', ['d' => $data->id]);
$actionbuttons = html_writer::link($redirectbackto, get_string('cancel'), ['class' => 'btn btn-secondary']);
$actionbuttons .= html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'saveandview',
'value' => get_string('save'), 'class' => 'btn btn-primary ml-2']);
if (!$rid && ((!$data->maxentries) ||
has_capability('mod/data:manageentries', $context) ||
(data_numentries($data) < ($data->maxentries - 1)))) {
$actionbuttons .= html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'saveandadd',
'value' => get_string('saveandadd', 'data'), 'class' => 'btn btn-primary ml-2']);
}
echo '</div>';
echo html_writer::div($actionbuttons, 'mdl-align mt-2');
echo $OUTPUT->box_end();
echo '</div></form>';

View File

@ -33,8 +33,10 @@ $exportuser = optional_param('exportuser', false, PARAM_BOOL); // Flag for expor
$exporttime = optional_param('exporttime', false, PARAM_BOOL); // Flag for exporting date/time information
$exportapproval = optional_param('exportapproval', false, PARAM_BOOL); // Flag for exporting user details
$tags = optional_param('exporttags', false, PARAM_BOOL); // Flag for exporting user details.
$redirectbackto = optional_param('backto', '', PARAM_LOCALURL); // The location to redirect back to.
$PAGE->set_url('/mod/data/export.php', array('d'=>$d));
$url = new moodle_url('/mod/data/export.php', array('d' => $d));
$PAGE->set_url($url);
if (! $data = $DB->get_record('data', array('id'=>$d))) {
print_error('wrongdataid', 'data');
@ -76,62 +78,62 @@ foreach ($fieldrecords as $fieldrecord) {
}
$mform = new mod_data_export_form('export.php?d='.$data->id, $fields, $cm, $data);
$mform = new mod_data_export_form(new moodle_url('/mod/data/export.php', ['d' => $data->id,
'backto' => $redirectbackto]), $fields, $cm, $data);
if($mform->is_cancelled()) {
redirect('view.php?d='.$data->id);
} elseif (!$formdata = (array) $mform->get_data()) {
// build header to match the rest of the UI
$PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($data->name), 2);
if ($mform->is_cancelled()) {
$redirectbackto = !empty($redirectbackto) ? $redirectbackto :
new \moodle_url('/mod/data/view.php', ['d' => $data->id]);
redirect($redirectbackto);
} else if ($formdata = (array) $mform->get_data()) {
$selectedfields = array();
foreach ($formdata as $key => $value) {
//field form elements are field_1 field_2 etc. 0 if not selected. 1 if selected.
if (strpos($key, 'field_')===0 && !empty($value)) {
$selectedfields[] = substr($key, 6);
}
}
// Render the activity information.
$cminfo = cm_info::create($cm);
$completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
$url = new moodle_url('/mod/data/export.php', array('d' => $d));
groups_print_activity_menu($cm, $url);
// these are for the tab display
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
$currenttab = 'export';
include('tabs.php');
$mform->display();
echo $OUTPUT->footer();
die;
}
$selectedfields = array();
foreach ($formdata as $key => $value) {
//field form elements are field_1 field_2 etc. 0 if not selected. 1 if selected.
if (strpos($key, 'field_')===0 && !empty($value)) {
$selectedfields[] = substr($key, 6);
$exportdata = data_get_exportdata($data->id, $fields, $selectedfields, $currentgroup, $context,
$exportuser, $exporttime, $exportapproval, $tags);
$count = count($exportdata);
switch ($formdata['exporttype']) {
case 'csv':
data_export_csv($exportdata, $formdata['delimiter_name'], $data->name, $count);
break;
case 'xls':
data_export_xls($exportdata, $data->name, $count);
break;
case 'ods':
data_export_ods($exportdata, $data->name, $count);
break;
}
}
$currentgroup = groups_get_activity_group($cm);
$exportdata = data_get_exportdata($data->id, $fields, $selectedfields, $currentgroup, $context,
$exportuser, $exporttime, $exportapproval, $tags);
$count = count($exportdata);
switch ($formdata['exporttype']) {
case 'csv':
data_export_csv($exportdata, $formdata['delimiter_name'], $data->name, $count);
break;
case 'xls':
data_export_xls($exportdata, $data->name, $count);
break;
case 'ods':
data_export_ods($exportdata, $data->name, $count);
break;
// Build header to match the rest of the UI.
$PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
$PAGE->set_secondary_active_tab('modulepage');
echo $OUTPUT->header();
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
}
// Render the activity information.
$cminfo = cm_info::create($cm);
$completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
groups_print_activity_menu($cm, $url);
$mform->display();
echo $OUTPUT->footer();
die();

View File

@ -25,12 +25,15 @@
require_once('../../config.php');
require_once('lib.php');
require_once($CFG->dirroot.'/mod/data/preset_form.php');
$id = optional_param('id', 0, PARAM_INT); // course module id
$d = optional_param('d', 0, PARAM_INT); // database id
$fid = optional_param('fid', 0 , PARAM_INT); // update field id
$newtype = optional_param('newtype','',PARAM_ALPHA); // type of the new field
$mode = optional_param('mode','',PARAM_ALPHA);
$action = optional_param('action', '', PARAM_ALPHA);
$fullname = optional_param('fullname', '', PARAM_PATH); // Directory the preset is in.
$defaultsort = optional_param('defaultsort', 0, PARAM_INT);
$defaultsortdir = optional_param('defaultsortdir', 0, PARAM_INT);
$cancel = optional_param('cancel', 0, PARAM_BOOL);
@ -58,6 +61,9 @@ if ($defaultsortdir !== 0) {
if ($cancel !== 0) {
$url->param('cancel', $cancel);
}
if ($action !== '') {
$url->param('action', $action);
}
if ($id) {
$url->param('id', $id);
@ -91,9 +97,69 @@ require_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/data:managetemplates', $context);
$formimportzip = new data_import_preset_zip_form();
$formimportzip->set_data(array('d' => $data->id));
$actionbar = new \mod_data\output\action_bar($data->id, $PAGE->url);
$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
$PAGE->set_heading($course->fullname);
// Fill in missing properties needed for updating of instance.
$data->course = $cm->course;
$data->cmidnumber = $cm->idnumber;
$data->instance = $cm->instance;
/************************************
* Data Processing *
***********************************/
$renderer = $PAGE->get_renderer('mod_data');
if ($formimportzip->is_cancelled()) {
redirect(new moodle_url('/mod/data/field.php', ['d' => $data->id]));
} else if ($formdata = $formimportzip->get_data()) {
$fieldactionbar = $actionbar->get_fields_action_bar();
data_print_header($course, $cm, $data, false, $fieldactionbar);
$file = new stdClass;
$file->name = $formimportzip->get_new_filename('importfile');
$file->path = $formimportzip->save_temp_file('importfile');
$importer = new data_preset_upload_importer($course, $cm, $data, $file->path);
echo $renderer->import_setting_mappings($data, $importer);
echo $OUTPUT->footer();
exit(0);
}
if ($action == 'finishimport' && confirm_sesskey()) {
data_print_header($course, $cm, $data, false);
$overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
if (!$fullname) {
$presetdir = $CFG->tempdir . '/forms/' . required_param('directory', PARAM_FILE);
if (!file_exists($presetdir) || !is_dir($presetdir)) {
throw new moodle_exception('cannotimport', 'error');
}
$importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
} else {
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
}
$importer->import($overwritesettings);
$strimportsuccess = get_string('importsuccess', 'data');
$straddentries = get_string('addentries', 'data');
$strtodatabase = get_string('todatabase', 'data');
if (!$DB->get_records('data_records', array('dataid' => $data->id))) {
echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase",
'notifysuccess');
} else {
echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
}
echo $OUTPUT->continue_button(new moodle_url('/mod/data/field.php', ['d' => $data->id]));
echo $OUTPUT->footer();
exit;
}
switch ($mode) {
case 'add': ///add a new field
@ -223,6 +289,32 @@ switch ($mode) {
}
break;
case 'import':
$fieldactionbar = $actionbar->get_fields_action_bar();
data_print_header($course, $cm, $data, false, $fieldactionbar);
echo $formimportzip->display();
echo $OUTPUT->footer();
exit;
case 'usepreset':
$fieldactionbar = $actionbar->get_fields_action_bar();
data_print_header($course, $cm, $data, false, $fieldactionbar);
if ($action === 'select') {
if (!empty($fullname)) {
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
echo $renderer->import_setting_mappings($data, $importer);
}
} else {
$presets = data_get_available_presets($context);
$presetstable = new \mod_data\output\presets($data->id, $presets,
new \moodle_url('/mod/data/field.php'));
echo $renderer->render_presets($presetstable, false);
}
echo $OUTPUT->footer();
exit;
default:
break;
}
@ -239,12 +331,10 @@ foreach ($plugins as $plugin=>$fulldir){
$menufield[$plugin] = get_string('pluginname', 'datafield_'.$plugin); //get from language files
}
asort($menufield); //sort in alphabetical order
$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
$PAGE->set_pagetype('mod-data-field-' . $newtype);
if (($mode == 'new') && (!empty($newtype)) && confirm_sesskey()) { /// Adding a new field
if (($mode == 'new') && (!empty($newtype))) { // Adding a new field.
data_print_header($course, $cm, $data,'fields');
$field = data_get_field_new($newtype, $data);
@ -257,7 +347,8 @@ if (($mode == 'new') && (!empty($newtype)) && confirm_sesskey()) { ///
$field->display_edit_field();
} else { /// Display the main listing of all fields
data_print_header($course, $cm, $data,'fields');
$fieldactionbar = $actionbar->get_fields_action_bar(true, true, true);
data_print_header($course, $cm, $data, 'fields', $fieldactionbar);
if (!$DB->record_exists('data_fields', array('dataid'=>$data->id))) {
echo $OUTPUT->notification(get_string('nofieldindatabase','data')); // nothing in database
@ -309,14 +400,6 @@ if (($mode == 'new') && (!empty($newtype)) && confirm_sesskey()) { ///
echo html_writer::table($table);
}
echo '<div class="fieldadd">';
$popupurl = $CFG->wwwroot.'/mod/data/field.php?d='.$data->id.'&mode=new&sesskey='. sesskey();
echo $OUTPUT->single_select(new moodle_url($popupurl), 'newtype', $menufield, null, array('' => 'choosedots'),
'fieldform', array('label' => get_string('newfield', 'data')));
echo $OUTPUT->help_icon('newfield', 'data');
echo '</div>';
echo '<div class="sortdefault">';
echo '<form id="sortdefault" action="'.$CFG->wwwroot.'/mod/data/field.php" method="get">';
echo '<div>';

View File

@ -33,6 +33,7 @@ $d = optional_param('d', 0, PARAM_INT); // database id
$rid = optional_param('rid', 0, PARAM_INT); // record id
$fielddelimiter = optional_param('fielddelimiter', ',', PARAM_CLEANHTML); // characters used as field delimiters for csv file import
$fieldenclosure = optional_param('fieldenclosure', '', PARAM_CLEANHTML); // characters used as record delimiters for csv file import
$redirectbackto = optional_param('backto', '', PARAM_LOCALURL); // The location to redirect back to.
$url = new moodle_url('/mod/data/import.php');
if ($rid !== 0) {
@ -65,38 +66,40 @@ require_login($course, false, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/data:manageentries', $context);
$form = new mod_data_import_form(new moodle_url('/mod/data/import.php'), ['dataid' => $data->id,
'backtourl' => $redirectbackto]);
if ($form->is_cancelled()) {
$redirectbackto = !empty($redirectbackto) ? $redirectbackto :
new \moodle_url('/mod/data/view.php', ['d' => $data->id]);
redirect($redirectbackto);
}
/// Print the page header
$PAGE->navbar->add(get_string('add', 'data'));
$PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
navigation_node::override_active_url(new moodle_url('/mod/data/import.php', array('d' => $data->id)));
$PAGE->set_secondary_active_tab('modulepage');
echo $OUTPUT->header();
echo $OUTPUT->heading_with_help(get_string('uploadrecords', 'mod_data'), 'uploadrecords', 'mod_data');
/// Groups needed for Add entry tab
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
if ($formdata = $form->get_data()) {
$filecontent = $form->get_file_content('recordsfile');
$recordsadded = data_import_csv($cm, $data, $filecontent, $formdata->encoding, $formdata->fielddelimiter);
$form = new mod_data_import_form(new moodle_url('/mod/data/import.php'), ['dataid' => $data->id]);
if (!$formdata = $form->get_data()) {
if ($recordsadded > 0) {
echo $OUTPUT->notification($recordsadded. ' '. get_string('recordssaved', 'data'), '');
} else {
echo $OUTPUT->notification(get_string('recordsnotsaved', 'data'), 'notifysuccess');
}
echo $OUTPUT->continue_button($redirectbackto);
} else {
/// Upload records section. Only for teachers and the admin.
echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthwide');
$form->display();
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
die;
} else {
$filecontent = $form->get_file_content('recordsfile');
$recordsadded = data_import_csv($cm, $data, $filecontent, $formdata->encoding, $formdata->fielddelimiter);
}
if ($recordsadded > 0) {
echo $OUTPUT->notification($recordsadded. ' '. get_string('recordssaved', 'data'), '');
} else {
echo $OUTPUT->notification(get_string('recordsnotsaved', 'data'), 'notifysuccess');
}
echo $OUTPUT->continue_button('import.php?d='.$data->id);
/// Finish the page
echo $OUTPUT->footer();

View File

@ -12,6 +12,7 @@ class mod_data_import_form extends moodleform {
$mform =& $this->_form;
$dataid = $this->_customdata['dataid'];
$backtourl = $this->_customdata['backtourl'];
$mform->addElement('filepicker', 'recordsfile', get_string('csvfile', 'data'));
@ -31,6 +32,11 @@ class mod_data_import_form extends moodleform {
$mform->setType('d', PARAM_INT);
$mform->setDefault('d', $dataid);
$this->add_action_buttons(false, get_string('submit'));
// Back to URL.
$mform->addElement('hidden', 'backto');
$mform->setType('backto', PARAM_LOCALURL);
$mform->setDefault('backto', $backtourl);
$this->add_action_buttons(true, get_string('submit'));
}
}

View File

@ -157,6 +157,7 @@ $string['exportentries'] = 'Export entries';
$string['exportformat'] = 'Export format';
$string['exportoptions'] = 'Export options';
$string['exportownentries'] = 'Export your own entries only? ({$a->mine}/{$a->all})';
$string['exportpreset'] = 'Export preset';
$string['failedpresetdelete'] = 'Error deleting a preset!';
$string['fieldadded'] = 'Field added';
$string['fieldallowautolink'] = 'Allow autolink';
@ -204,6 +205,7 @@ $string['chooseexportformat'] = 'Choose the format you wish to export to';
$string['chooseorupload'] = 'Choose file';
$string['expired'] = 'Sorry, this activity closed on {$a} and is no longer available';
$string['importentries'] = 'Import entries';
$string['importpreset'] = 'Import a preset';
$string['importsuccess'] = 'The preset has been successfully applied.';
$string['includeapproval'] = 'Include approval status';
$string['includetags'] = 'Include tags';
@ -238,6 +240,7 @@ $string['latlongkmllabelling'] = 'How to label items in KML files (Google Earth)
$string['latlonglinkservicesdisplayed'] = 'Link-out services to display';
$string['latlongotherfields'] = 'Other fields';
$string['list'] = 'View list';
$string['listview'] = 'List view';
$string['listtemplate'] = 'List template';
$string['longitude'] = 'Longitude';
$string['manageapproved'] = 'Allow editing of approved entries';
@ -311,6 +314,7 @@ $string['pluginadministration'] = 'Database activity administration';
$string['pluginname'] = 'Database';
$string['portfolionotfile'] = 'Export to a portfolio rather than a file (csv and leap2a only)';
$string['presetinfo'] = 'Saving as a preset will publish this template. Other users may be able to use it in their databases.';
$string['presetnotselected'] = 'No preset has been selected.';
$string['presets'] = 'Presets';
$string['privacy:metadata:commentpurpose'] = 'Comments on database records';
$string['privacy:metadata:data_content'] = 'Represents one answer to one field in database activity module';
@ -364,6 +368,8 @@ $string['saveandadd'] = 'Save and add another';
$string['saveandview'] = 'Save and view';
$string['saveaspreset'] = 'Save as preset';
$string['saveaspreset_help'] = 'The save as preset feature publishes the templates and fields as a preset which others on the site can then use. (You may delete it from the list of presets at any time.)';
$string['savedataaspreset'] = 'Save all fields and templates as preset';
$string['saveaspresetmissingcapability'] = 'The user does not have the right permissions to save the database as a preset.';
$string['savesettings'] = 'Save settings';
$string['savesuccess'] = 'Saved successfully. Your preset will now be available across the site.';
$string['savetemplate'] = 'Save template';
@ -375,6 +381,7 @@ $string['selectfields'] = 'Select fields';
$string['selectexportoptions'] = 'Select export options';
$string['showall'] = 'Show all entries';
$string['single'] = 'View single';
$string['singleview'] = 'Single view';
$string['singletemplate'] = 'Single template';
$string['subplugintype_datafield'] = 'Database field type';
$string['subplugintype_datafield_plural'] = 'Database field types';
@ -408,6 +415,8 @@ The field enclosure is a character that surrounds each field in each record. It
$string['uploadrecords_link'] = 'mod/data/import';
$string['url'] = 'URL';
$string['usedate'] = 'Include in search.';
$string['usepredefinedset'] = 'Use predefined set';
$string['usepreset'] = 'Use preset';
$string['usestandard'] = 'Use a preset';
$string['usestandard_help'] = 'To use a preset available to the whole site, select it from the list. (If you have added a preset to the list using the save as preset feature then you have the option of deleting it.)';
$string['viewfromdate'] = 'Read only from';

View File

@ -353,10 +353,12 @@ class data_field_base { // Base class for Database Field Types (see field/*/
require_once($CFG->dirroot.'/mod/data/field/'.$this->type.'/mod.html');
echo '<div class="mdl-align">';
echo '<input type="submit" class="btn btn-primary" value="'.$savebutton.'" />'."\n";
echo '<input type="submit" class="btn btn-secondary" name="cancel" value="'.get_string('cancel').'" />'."\n";
echo '</div>';
echo html_writer::start_div('mt-3');
echo html_writer::tag('input', null, array('type' => 'submit', 'value' => $savebutton,
'class' => 'btn btn-primary'));
echo html_writer::tag('input', null, array('type' => 'submit', 'name' => 'cancel',
'value' => get_string('cancel'), 'class' => 'btn btn-secondary ml-2'));
echo html_writer::end_div();
echo '</form>';
@ -1420,8 +1422,16 @@ function data_print_template($template, $records, $data, $search='', $page=0, $r
$patterns[]='##edit##';
$patterns[]='##delete##';
if (data_user_can_manage_entry($record, $data, $context)) {
$backtourlparams = [
'd' => $data->id,
];
if ($template === 'singletemplate') {
$backtourlparams['mode'] = 'single';
}
$backtourl = new \moodle_url('/mod/data/view.php', $backtourlparams);
$replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/edit.php?d='
.$data->id.'&amp;rid='.$record->id.'&amp;sesskey='.sesskey().'">' .
.$data->id.'&amp;rid='.$record->id.'&amp;sesskey='.sesskey().'&amp;backto='
. urlencode($backtourl->out(false)) .'">' .
$OUTPUT->pix_icon('t/edit', get_string('edit')) . '</a>';
$replacement[] = '<a href="'.$CFG->wwwroot.'/mod/data/view.php?d='
.$data->id.'&amp;delete='.$record->id.'&amp;sesskey='.sesskey().'">' .
@ -2302,14 +2312,18 @@ function data_delete_site_preset($name) {
* @param stdClass $cm
* @param stdClass $data
* @param string $currenttab
* @param string $actionbar
*/
function data_print_header($course, $cm, $data, $currenttab='') {
function data_print_header($course, $cm, $data, $currenttab='', string $actionbar = '') {
global $CFG, $displaynoticegood, $displaynoticebad, $OUTPUT, $PAGE, $USER;
$PAGE->set_title($data->name);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($data->name), 2);
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
}
// Render the activity information.
$cminfo = cm_info::create($cm);
@ -2319,15 +2333,7 @@ function data_print_header($course, $cm, $data, $currenttab='') {
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
// Groups needed for Add entry tab
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
// Print the tabs
if ($currenttab) {
include('tabs.php');
}
echo $actionbar;
// Print any notices
@ -2524,7 +2530,8 @@ abstract class data_preset_importer {
* @return stdClass
*/
public function get_preset_settings() {
global $DB;
global $DB, $CFG;
require_once($CFG->libdir.'/xmlize.php');
$fs = $fileobj = null;
if (!is_directory_a_preset($this->directory)) {
@ -3605,16 +3612,22 @@ function data_extend_settings_navigation(settings_navigation $settings, navigati
} else {
$addstring = get_string('editentry', 'data');
}
$datanode->add($addstring, new moodle_url('/mod/data/edit.php', array('d'=>$PAGE->cm->instance)));
$addentrynode = $datanode->add($addstring,
new moodle_url('/mod/data/edit.php', array('d' => $PAGE->cm->instance)));
$addentrynode->set_show_in_secondary_navigation(false);
}
if (has_capability(DATA_CAP_EXPORT, $PAGE->cm->context)) {
// The capability required to Export database records is centrally defined in 'lib.php'
// and should be weaker than those required to edit Templates, Fields and Presets.
$datanode->add(get_string('exportentries', 'data'), new moodle_url('/mod/data/export.php', array('d'=>$data->id)));
$exportentriesnode = $datanode->add(get_string('exportentries', 'data'),
new moodle_url('/mod/data/export.php', array('d' => $data->id)));
$exportentriesnode->set_show_in_secondary_navigation(false);
}
if (has_capability('mod/data:manageentries', $PAGE->cm->context)) {
$datanode->add(get_string('importentries', 'data'), new moodle_url('/mod/data/import.php', array('d'=>$data->id)));
$importentriesnode = $datanode->add(get_string('importentries', 'data'),
new moodle_url('/mod/data/import.php', array('d' => $data->id)));
$importentriesnode->set_show_in_secondary_navigation(false);
}
if (has_capability('mod/data:managetemplates', $PAGE->cm->context)) {
@ -3629,15 +3642,17 @@ function data_extend_settings_navigation(settings_navigation $settings, navigati
$defaultemplate = 'singletemplate';
}
$templates = $datanode->add(get_string('templates', 'data'));
$datanode->add(get_string('fields', 'data'),
new moodle_url('/mod/data/field.php', array('d' => $data->id)));
$templates = $datanode->add(get_string('templates', 'data'),
new moodle_url('/mod/data/templates.php', array('d' => $data->id)));
$templatelist = array ('listtemplate', 'singletemplate', 'asearchtemplate', 'addtemplate', 'rsstemplate', 'csstemplate', 'jstemplate');
foreach ($templatelist as $template) {
$templates->add(get_string($template, 'data'), new moodle_url('/mod/data/templates.php', array('d'=>$data->id,'mode'=>$template)));
}
$datanode->add(get_string('fields', 'data'), new moodle_url('/mod/data/field.php', array('d'=>$data->id)));
$datanode->add(get_string('presets', 'data'), new moodle_url('/mod/data/preset.php', array('d'=>$data->id)));
$datanode->add(get_string('presets', 'data'), new moodle_url('/mod/data/preset.php', array('d' => $data->id)));
}
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {

View File

@ -31,24 +31,34 @@
require_once('../../config.php');
require_once($CFG->dirroot.'/mod/data/lib.php');
require_once($CFG->dirroot.'/mod/data/preset_form.php');
require_once($CFG->libdir.'/xmlize.php');
$id = optional_param('id', 0, PARAM_INT); // course module id
$id = optional_param('id', 0, PARAM_INT); // The course module id.
if ($id) {
$cm = get_coursemodule_from_id('data', $id, null, null, MUST_EXIST);
$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
$data = $DB->get_record('data', array('id'=>$cm->instance), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
$data = $DB->get_record('data', array('id' => $cm->instance), '*', MUST_EXIST);
} else {
$d = required_param('d', PARAM_INT); // database activity id
$data = $DB->get_record('data', array('id'=>$d), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id'=>$data->course), '*', MUST_EXIST);
$data = $DB->get_record('data', array('id' => $d), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $data->course), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('data', $data->id, $course->id, null, MUST_EXIST);
}
$action = optional_param('action', 'view', PARAM_ALPHA); // The page action.
$allowedactions = ['view', 'delete', 'confirmdelete', 'import', 'importzip', 'finishimport',
'export'];
if (!in_array($action, $allowedactions)) {
throw new moodle_exception('invalidaccess');
}
$context = context_module::instance($cm->id, MUST_EXIST);
require_login($course, false, $cm);
require_capability('mod/data:managetemplates', $context);
$PAGE->set_url(new moodle_url('/mod/data/preset.php', array('d'=>$data->id)));
$url = new moodle_url('/mod/data/preset.php', array('d' => $data->id));
$PAGE->set_url($url);
$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
@ -58,211 +68,137 @@ $data->course = $cm->course;
$data->cmidnumber = $cm->idnumber;
$data->instance = $cm->instance;
$renderer = $PAGE->get_renderer('mod_data');
$presets = data_get_available_presets($context);
$strdelete = get_string('deleted', 'data');
foreach ($presets as &$preset) {
if (!empty($preset->userid)) {
$userfieldsapi = \core_user\fields::for_name();
$namefields = $userfieldsapi->get_sql('', false, '', '', false)->selects;
$presetuser = $DB->get_record('user', array('id' => $preset->userid), 'id, ' . $namefields, MUST_EXIST);
$preset->description = $preset->name.' ('.fullname($presetuser, true).')';
} else {
$preset->userid = 0;
$preset->description = $preset->name;
if (data_user_can_delete_preset($context, $preset) && $preset->name != 'Image gallery') {
$delurl = new moodle_url('/mod/data/preset.php', array('d'=> $data->id, 'action'=>'confirmdelete', 'fullname'=>$preset->userid.'/'.$preset->shortname, 'sesskey'=>sesskey()));
$delicon = $OUTPUT->pix_icon('t/delete', $strdelete . ' ' . $preset->description);
$preset->description .= html_writer::link($delurl, $delicon);
}
}
if ($preset->userid > 0 && data_user_can_delete_preset($context, $preset)) {
$delurl = new moodle_url('/mod/data/preset.php', array('d'=> $data->id, 'action'=>'confirmdelete', 'fullname'=>$preset->userid.'/'.$preset->shortname, 'sesskey'=>sesskey()));
$delicon = $OUTPUT->pix_icon('t/delete', $strdelete . ' ' . $preset->description);
$preset->description .= html_writer::link($delurl, $delicon);
if ($action === 'export') {
if (headers_sent()) {
print_error('headersent');
}
$exportfile = data_presets_export($course, $cm, $data);
$exportfilename = basename($exportfile);
header("Content-Type: application/download\n");
header("Content-Disposition: attachment; filename=\"$exportfilename\"");
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
header('Pragma: public');
// If this file was requested from a form, then mark download as complete.
\core_form\util::form_download_complete();
$exportfilehandler = fopen($exportfile, 'rb');
print fread($exportfilehandler, filesize($exportfile));
fclose($exportfilehandler);
unlink($exportfile);
exit(0);
}
// This is required because its currently bound to the last element in the array.
// If someone were to inadvently use it again and this call were not here
unset($preset);
$form_importexisting = new data_existing_preset_form(null, array('presets'=>$presets));
$form_importexisting->set_data(array('d' => $data->id));
$formimportzip = new data_import_preset_zip_form();
$formimportzip->set_data(array('d' => $data->id));
$form_importzip = new data_import_preset_zip_form();
$form_importzip->set_data(array('d' => $data->id));
if ($formimportzip->is_cancelled()) {
redirect(new moodle_url('/mod/data/preset.php', ['d' => $data->id]));
}
$form_export = new data_export_form();
$form_export->set_data(array('d' => $data->id));
$form_save = new data_save_preset_form();
$form_save->set_data(array('d' => $data->id, 'name'=>$data->name));
/* Output */
if (!$form_export->is_submitted()) {
echo $OUTPUT->header();
echo $OUTPUT->header();
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
// Render the activity information.
$cminfo = cm_info::create($cm);
$completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
// Needed for tabs.php
$currenttab = 'presets';
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
include('tabs.php');
}
if (optional_param('sesskey', false, PARAM_BOOL) && confirm_sesskey()) {
if ($formdata = $formimportzip->get_data()) {
$file = new stdClass;
$file->name = $formimportzip->get_new_filename('importfile');
$file->path = $formimportzip->save_temp_file('importfile');
$importer = new data_preset_upload_importer($course, $cm, $data, $file->path);
echo $renderer->import_setting_mappings($data, $importer);
echo $OUTPUT->footer();
exit(0);
}
$renderer = $PAGE->get_renderer('mod_data');
if (in_array($action, ['confirmdelete', 'delete', 'finishimport'])) {
$fullname = optional_param('fullname', '' , PARAM_PATH); // The directory the preset is in.
// Find out preset owner userid and shortname.
$parts = explode('/', $fullname, 2);
$userid = empty($parts[0]) ? 0 : (int)$parts[0];
$shortname = empty($parts[1]) ? '' : $parts[1];
echo html_writer::start_div('overflow-hidden');
if ($formdata = $form_importexisting->get_data()) {
$importer = new data_preset_existing_importer($course, $cm, $data, $formdata->fullname);
echo $renderer->import_setting_mappings($data, $importer);
if ($action === 'confirmdelete') {
$path = data_preset_path($course, $userid, $shortname);
$strwarning = get_string('deletewarning', 'data').'<br />'.$shortname;
$optionsyes = [
'fullname' => $fullname,
'action' => 'delete',
'd' => $data->id,
];
$optionsno = ['d' => $data->id];
echo $OUTPUT->confirm($strwarning, new moodle_url('/mod/data/preset.php', $optionsyes),
new moodle_url('/mod/data/preset.php', $optionsno));
echo $OUTPUT->footer();
exit(0);
} else if ($formdata = $form_importzip->get_data()) {
$file = new stdClass;
$file->name = $form_importzip->get_new_filename('importfile');
$file->path = $form_importzip->save_temp_file('importfile');
$importer = new data_preset_upload_importer($course, $cm, $data, $file->path);
echo $renderer->import_setting_mappings($data, $importer);
echo $OUTPUT->footer();
exit(0);
} else if ($formdata = $form_export->get_data()) {
if (headers_sent()) {
print_error('headersent');
} else if ($action === 'delete') {
if (!confirm_sesskey()) {
throw new moodle_exception('invalidsesskey');
}
$exportfile = data_presets_export($course, $cm, $data);
$exportfilename = basename($exportfile);
header("Content-Type: application/download\n");
header("Content-Disposition: attachment; filename=\"$exportfilename\"");
header('Expires: 0');
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
header('Pragma: public');
// If this file was requested from a form, then mark download as complete.
\core_form\util::form_download_complete();
$exportfilehandler = fopen($exportfile, 'rb');
print fread($exportfilehandler, filesize($exportfile));
fclose($exportfilehandler);
unlink($exportfile);
exit(0);
} else if ($formdata = $form_save->get_data()) {
if (!empty($formdata->overwrite)) {
$selectedpreset = new stdClass();
foreach ($presets as $preset) {
if ($preset->name == $formdata->name) {
$selectedpreset = $preset;
break;
}
}
if (isset($selectedpreset->name)) {
if (data_user_can_delete_preset($context, $selectedpreset)) {
data_delete_site_preset($formdata->name);
} else {
print_error('cannotoverwritepreset', 'data');
}
$selectedpreset = new stdClass();
foreach ($presets as $preset) {
if ($preset->shortname == $shortname) {
$selectedpreset = $preset;
}
}
// If the preset exists now then we need to throw an error.
$sitepresets = data_get_available_site_presets($context);
foreach ($sitepresets as $key=>$preset) {
if ($formdata->name == $preset->name) {
print_error('errorpresetexists', 'preset');
}
if (!isset($selectedpreset->shortname) || !data_user_can_delete_preset($context, $selectedpreset)) {
print_error('invalidrequest');
}
// Save the preset now
data_presets_save($course, $cm, $data, $formdata->name);
echo $OUTPUT->notification(get_string('savesuccess', 'data'), 'notifysuccess');
echo $OUTPUT->continue_button($PAGE->url);
echo $OUTPUT->footer();
exit(0);
} else {
$action = optional_param('action', null, PARAM_ALPHANUM);
$fullname = optional_param('fullname', '', PARAM_PATH); // directory the preset is in
//
// find out preset owner userid and shortname
$parts = explode('/', $fullname, 2);
$userid = empty($parts[0]) ? 0 : (int)$parts[0];
$shortname = empty($parts[1]) ? '' : $parts[1];
if ($userid && ($userid != $USER->id) && !has_capability('mod/data:viewalluserpresets', $context)) {
print_error('cannotaccesspresentsother', 'data');
data_delete_site_preset($shortname);
$strdeleted = get_string('deleted', 'data');
echo $OUTPUT->notification("$shortname $strdeleted", 'notifysuccess');
} else if ($action === 'finishimport') {
if (!confirm_sesskey()) {
throw new moodle_exception('invalidsesskey');
}
if ($action == 'confirmdelete') {
$path = data_preset_path($course, $userid, $shortname);
$strwarning = get_string('deletewarning', 'data').'<br />'.$shortname;
$optionsyes = array('fullname' => $userid.'/'.$shortname,
'action' => 'delete',
'd' => $data->id);
$optionsno = array('d' => $data->id);
echo $OUTPUT->confirm($strwarning, new moodle_url('preset.php', $optionsyes), new moodle_url('preset.php', $optionsno));
echo $OUTPUT->footer();
exit(0);
} else if ($action == 'delete') {
$selectedpreset = new stdClass();
foreach ($presets as $preset) {
if ($preset->shortname == $shortname) {
$selectedpreset = $preset;
}
}
if (!isset($selectedpreset->shortname) || !data_user_can_delete_preset($context, $selectedpreset)) {
print_error('invalidrequest');
}
data_delete_site_preset($shortname);
$strdeleted = get_string('deleted', 'data');
echo $OUTPUT->notification("$shortname $strdeleted", 'notifysuccess');
} else if ($action == 'finishimport') {
$overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
if (!$fullname) {
$presetdir = $CFG->tempdir.'/forms/'.required_param('directory', PARAM_FILE);
if (!file_exists($presetdir) || !is_dir($presetdir)) {
print_error('cannotimport');
}
$importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
} else {
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
}
$importer->import($overwritesettings);
$strimportsuccess = get_string('importsuccess', 'data');
$straddentries = get_string('addentries', 'data');
$strtodatabase = get_string('todatabase', 'data');
if (!$DB->get_records('data_records', array('dataid'=>$data->id))) {
echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase", 'notifysuccess');
} else {
echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
$overwritesettings = optional_param('overwritesettings', false, PARAM_BOOL);
if (!$fullname) {
$presetdir = $CFG->tempdir.'/forms/'.required_param('directory', PARAM_FILE);
if (!file_exists($presetdir) || !is_dir($presetdir)) {
print_error('cannotimport');
}
$importer = new data_preset_upload_importer($course, $cm, $data, $presetdir);
} else {
$importer = new data_preset_existing_importer($course, $cm, $data, $fullname);
}
$importer->import($overwritesettings);
$strimportsuccess = get_string('importsuccess', 'data');
$straddentries = get_string('addentries', 'data');
$strtodatabase = get_string('todatabase', 'data');
if (!$DB->get_records('data_records', array('dataid'=>$data->id))) {
echo $OUTPUT->notification("$strimportsuccess <a href='edit.php?d=$data->id'>$straddentries</a> $strtodatabase", 'notifysuccess');
} else {
echo $OUTPUT->notification("$strimportsuccess", 'notifysuccess');
}
echo $OUTPUT->continue_button($PAGE->url);
echo $OUTPUT->footer();
exit(0);
}
echo $OUTPUT->continue_button(new moodle_url('/mod/data/preset.php', ['d' => $data->id]));
echo html_writer::end_div();
echo $OUTPUT->footer();
exit(0);
}
// Export forms
echo $OUTPUT->heading(get_string('export', 'data'), 3);
$form_export->display();
$form_save->display();
// Render the activity information.
$cminfo = cm_info::create($cm);
$completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
// Import forms
echo $OUTPUT->heading(get_string('import'), 3);
$form_importzip->display();
$form_importexisting->display();
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
if ($action === 'import') {
echo $formimportzip->display();
} else {
$actionbar = new \mod_data\output\action_bar($data->id, $url);
echo $actionbar->get_presets_action_bar();
$presets = new \mod_data\output\presets($data->id, $presets, new \moodle_url('/mod/data/field.php'), true);
echo $renderer->render_presets($presets);
}
echo $OUTPUT->footer();

View File

@ -30,11 +30,17 @@ class data_import_preset_zip_form extends moodleform {
$this->_form->addElement('hidden', 'd');
$this->_form->setType('d', PARAM_INT);
$this->_form->addElement('hidden', 'mode', 'import');
$this->_form->setType('mode', PARAM_ALPHANUM);
$this->_form->addElement('hidden', 'action', 'importzip');
$this->_form->setType('action', PARAM_ALPHANUM);
$this->_form->addElement('filepicker', 'importfile', get_string('chooseorupload', 'data'));
$this->_form->addRule('importfile', null, 'required');
$this->_form->addElement('submit', 'uploadzip', get_string('import'));
$buttons = [
$this->_form->createElement('submit', 'submitbutton', get_string('save')),
$this->_form->createElement('cancel'),
];
$this->_form->addGroup($buttons, 'buttonar', '', [' '], false);
}
}

View File

@ -85,4 +85,58 @@ class mod_data_renderer extends plugin_renderer_base {
return $html;
}
/**
* Renders the action bar for the field page.
*
* @param \mod_data\output\fields_action_bar $actionbar
* @return string The HTML output
*/
public function render_fields_action_bar(\mod_data\output\fields_action_bar $actionbar): string {
$data = $actionbar->export_for_template($this);
return $this->render_from_template('mod_data/fields_action_bar', $data);
}
/**
* Renders the action bar for the view page.
*
* @param \mod_data\output\view_action_bar $actionbar
* @return string The HTML output
*/
public function render_view_action_bar(\mod_data\output\view_action_bar $actionbar): string {
$data = $actionbar->export_for_template($this);
return $this->render_from_template('mod_data/view_action_bar', $data);
}
/**
* Renders the action bar for the template page.
*
* @param \mod_data\output\templates_action_bar $actionbar
* @return string The HTML output
*/
public function render_templates_action_bar(\mod_data\output\templates_action_bar $actionbar): string {
$data = $actionbar->export_for_template($this);
return $this->render_from_template('mod_data/templates_action_bar', $data);
}
/**
* Renders the action bar for the preset page.
*
* @param \mod_data\output\presets_action_bar $actionbar
* @return string The HTML output
*/
public function render_presets_action_bar(\mod_data\output\presets_action_bar $actionbar): string {
$data = $actionbar->export_for_template($this);
return $this->render_from_template('mod_data/presets_action_bar', $data);
}
/**
* Renders the presets table in the preset page.
*
* @param \mod_data\output\presets $presets
* @return string The HTML output
*/
public function render_presets(\mod_data\output\presets $presets): string {
$data = $presets->export_for_template($this);
return $this->render_from_template('mod_data/presets', $data);
}
}

View File

@ -56,12 +56,10 @@
}
/** Styles for field.php **/
.path-mod-data-field .fieldadd,
.path-mod-data-field .sortdefault {
margin: 1em 0;
}
.path-mod-data-field .fieldadd select,
.path-mod-data-field .sortdefault select {
margin-left: 1em;
}

View File

@ -32,13 +32,9 @@ $mode = optional_param('mode', 'singletemplate', PARAM_ALPHA);
$useeditor = optional_param('useeditor', null, PARAM_BOOL);
$url = new moodle_url('/mod/data/templates.php');
if ($mode !== 'singletemplate') {
$url->param('mode', $mode);
}
if ($id) {
$url->param('id', $id);
$PAGE->set_url($url);
if (! $cm = get_coursemodule_from_id('data', $id)) {
print_error('invalidcoursemodule');
}
@ -51,7 +47,6 @@ if ($id) {
} else {
$url->param('d', $d);
$PAGE->set_url($url);
if (! $data = $DB->get_record('data', array('id'=>$d))) {
print_error('invalidid', 'data');
}
@ -63,6 +58,9 @@ if ($id) {
}
}
$url->param('mode', $mode);
$PAGE->set_url($url);
require_login($course, false, $cm);
$context = context_module::instance($cm->id);
@ -104,24 +102,22 @@ $PAGE->set_title($data->name);
$PAGE->set_heading($course->fullname);
$PAGE->set_pagelayout('admin');
$PAGE->force_settings_menu(true);
echo $OUTPUT->header();
echo $OUTPUT->heading(format_string($data->name), 2);
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
}
// Render the activity information.
$cminfo = cm_info::create($cm);
$completiondetails = \core_completion\cm_completion_details::get_instance($cminfo, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cminfo, $USER->id);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
echo $OUTPUT->activity_information($cminfo, $completiondetails, $activitydates);
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
/// Groups needed for Add entry tab
$currentgroup = groups_get_activity_group($cm);
$groupmode = groups_get_activity_groupmode($cm);
/// Print the tabs.
$currenttab = 'templates';
include('tabs.php');
$actionbar = new \mod_data\output\action_bar($data->id, $url);
echo $actionbar->get_templates_action_bar();
/// Processing submitted data, i.e updating form.
$resettemplate = false;
@ -319,24 +315,6 @@ if ($mode != 'csstemplate' and $mode != 'jstemplate') {
echo '</select>';
echo '</div>';
echo '<br /><br /><br /><br />';
echo '<input type="submit" class="btn btn-secondary" name="defaultform" value="'.get_string('resettemplate', 'data').'" />';
echo '<br /><br />';
if ($usehtmleditor) {
$switchlink = new moodle_url($PAGE->url, ['useeditor' => false]);
echo html_writer::link($switchlink, get_string('editordisable', 'data'));
} else {
$switchlink = new moodle_url($PAGE->url, ['useeditor' => true]);
echo html_writer::link($switchlink, get_string('editorenable', 'data'), [
'id' => 'enabletemplateeditor',
]);
$PAGE->requires->event_handler('#enabletemplateeditor', 'click', 'M.util.show_confirm_dialog', [
'message' => get_string('enabletemplateeditorcheck', 'data'),
]);
}
} else {
echo '<br /><br /><br /><br />';
echo '<input type="submit" class="btn btn-primary" name="defaultform" value="' . get_string('resettemplate', 'data') . '" />';
}
echo '</td>';
@ -391,11 +369,26 @@ if ($mode == 'listtemplate'){
echo '</tr>';
}
echo '<tr><td class="save_template" colspan="2">';
echo '<input type="submit" class="btn btn-primary" value="'.get_string('savetemplate','data').'" />&nbsp;';
echo '</table>';
echo html_writer::start_div('container-fluid mt-4');
echo html_writer::start_div('row');
echo '</td></tr></table>';
$resettemplatebutton = html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'defaultform',
'class' => 'btn btn-secondary', 'value' => get_string('resettemplate', 'data')]);
$savetemplatebutton = html_writer::empty_tag('input', ['type' => 'submit', 'class' => 'btn btn-primary ml-2',
'value' => get_string('savetemplate', 'data')]);
echo html_writer::div($resettemplatebutton . $savetemplatebutton);
if ($mode != 'csstemplate' and $mode != 'jstemplate') {
// Output the toggle template editor element.
$toggletemplateeditor = html_writer::checkbox('useeditor', 1, $usehtmleditor,
get_string('editorenable', 'data'), null, ['class' => 'pl-2']);
echo html_writer::div($toggletemplateeditor, 'ml-auto');
$PAGE->requires->js_call_amd('mod_data/templateseditor', 'init', ['d' => $d, 'mode' => $mode]);
}
echo html_writer::end_div();
echo html_writer::end_div();
echo $OUTPUT->box_end();
echo '</div>';

View File

@ -0,0 +1,109 @@
{{!
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/>.
}}
{{!
@template mod_data/fields_action_bar
Actions bar at the top of the field pages in the database activity.
Context variables required for this template:
* d - The database id.
* urlselect - The data object containing the required properties to render core/url_select.
* fieldselect - The data object containing the required properties to render core/single_select.
* saveaspreset - Whether to display the save as preset button (mod_data/save_as_preset).
* exportpreset - The data object containing the required properties to render core/single_button.
Example context (json):
{
"d": 1,
"urlselect": {
"id": "url_select_test",
"action": "https://example.com/post",
"formid": "url_select_form",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "Some name",
"value": "/mod/data/someurl.php",
"selected": false
}
],
"disabled": false,
"title": null
},
"fieldselect": {
"id": "single_select_test",
"name": "fieldselector",
"method": "get",
"action": "https://example.com/post",
"formid": "single_select_form",
"sesskey": "sesskey",
"classes": "singleselect",
"label": "",
"helpicon": false,
"options": [
{
"name": "Some name",
"value": "somevalue",
"selected": false,
"optgroup": false
}
],
"disabled": false,
"title": null
},
"saveaspreset": true,
"exportpreset": {
"id": "single_button_test",
"method" : "post",
"formid": "single_button_form",
"url" : "https://example.com/post",
"primary" : false,
"tooltip" : null,
"label" : "Label",
"attributes": []
}
}
}}
<div class="container-fluid mb-5">
<div class="row">
<div class="d-flex">
<div>
{{#urlselect}}
{{>core/url_select}}
{{/urlselect}}
</div>
<div class='pl-2 fieldadd'>
{{#fieldselect}}
{{>core/single_select}}
{{/fieldselect}}
</div>
</div>
<div class="ml-auto d-flex">
<div>
{{#saveaspreset}}
{{>mod_data/save_as_preset}}
{{/saveaspreset}}
</div>
<div class="pl-2">
{{#exportpreset}}
{{>core/single_button}}
{{/exportpreset}}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,43 @@
{{!
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/>.
}}
{{!
@template mod_data/presets
Form containing all database presets displayed within a table.
Context variables required for this template:
* formactionul - The form action url.
* d - The database id.
* presetstable - The HTML output of the table with presets
Example context (json):
{
"formactionul": "http://www.example.com",
"d": 1,
"presetstable": "<table></table>"
}
}}
<h4>{{#str}}presets, mod_data{{/str}}</h4>
<form method="post" action="{{formactionul}}" class="mt-4">
<input type="hidden" name="d" value="{{d}}">
<input type="hidden" name="mode" value="usepreset">
<input type="hidden" name="action" value="select">
{{{presetstable}}}
<input type="submit" name="selectpreset" value="{{#str}}usepreset, mod_data{{/str}}" class="btn btn-primary mt-2">
</form>
{{#js}}
require(['mod_data/selectpreset'], function(selectPreset) {
selectPreset.init();
});
{{/js}}

View File

@ -0,0 +1,33 @@
{{!
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/>.
}}
{{!
@template mod_data/presets_action_bar
Actions bar at the top of the presets page in the database activity.
Context variables required for this template:
* importpreseturl - The url to the import preset page.
Example context (json):
{
"importpreseturl": "http://www.example.com"
}
}}
<div class="container-fluid mb-5">
<div class="row">
<div class="d-flex">
<a href="{{importpreseturl}}" class="btn btn-secondary">{{#str}}import, core{{/str}}</a>
</div>
</div>
</div>

View File

@ -0,0 +1,40 @@
{{!
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/>.
}}
{{!
@template mod_data/save_as_preset
Trigger button for the save as preset modal form.
Classes required for JS:
* none
Data attributes required for JS:
* All data attributes are required
Context variables required for this template:
* d - The database id.
Example context (json):
{
"d": 1
}
}}
<button type="button" class="btn btn-secondary" data-action="saveaspreset" data-dataid={{d}}>
{{#str}}saveaspreset, mod_data{{/str}}
</button>
{{#js}}
require(['mod_data/saveaspreset'], function(saveAsPreset) {
saveAsPreset.init();
});
{{/js}}

View File

@ -0,0 +1,82 @@
{{!
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/>.
}}
{{!
@template mod_data/templates_action_bar
Actions bar at the top of the template pages in the database activity.
Context variables required for this template:
* d - The database id.
* urlselect - The data object containing the required properties to render core/url_select.
* saveaspreset - Whether to display the save as preset button (mod_data/save_as_preset).
* exportpreset - The data object containing the required properties to render core/single_button.
Example context (json):
{
"d": 1,
"urlselect": {
"id": "url_select_test",
"action": "https://example.com/post",
"formid": "url_select_form",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "Some name",
"value": "/mod/data/someurl.php",
"selected": false
}
],
"disabled": false,
"title": null
},
"saveaspreset": true,
"exportpreset": {
"id": "single_button_test",
"method" : "post",
"formid": "single_button_form",
"url" : "https://example.com/post",
"primary" : false,
"tooltip" : null,
"label" : "Label",
"attributes": []
}
}
}}
<div class="container-fluid mb-4">
<div class="row">
<div class="d-flex">
<div>
{{#urlselect}}
{{>core/url_select}}
{{/urlselect}}
</div>
</div>
<div class="ml-auto d-flex">
<div>
{{#saveaspreset}}
{{>mod_data/save_as_preset}}
{{/saveaspreset}}
</div>
<div class="pl-2">
{{#exportpreset}}
{{>core/single_button}}
{{/exportpreset}}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,94 @@
{{!
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/>.
}}
{{!
@template mod_data/view_action_bar
Actions bar at the top of the view pages in the database activity.
Context variables required for this template:
* urlselect - The data object containing the required properties to render core/url_select.
* importentriesbutton - The data object containing the required properties to render core/single_button.
* exportentriesbutton - The data object containing the required properties to render core/single_button.
Example context (json):
{
"urlselect": {
"id": "url_select_test",
"action": "https://example.com/post",
"formid": "url_select_form",
"sesskey": "sesskey",
"classes": "urlselect",
"label": "",
"helpicon": false,
"showbutton": null,
"options": [
{
"name": "Some name",
"value": "/mod/data/someurl.php",
"selected": false
}
],
"disabled": false,
"title": null
},
"importentriesbutton": {
"id": "single_button_test_1",
"method" : "post",
"formid": "single_button_form_1",
"url" : "http://example.com/post",
"primary" : false,
"tooltip" : null,
"label" : "Label",
"attributes": []
},
"exportentriesbutton": {
"id": "single_button_test_2",
"method" : "post",
"formid": "single_button_form_2",
"url" : "http://example.com/post",
"primary" : false,
"tooltip" : null,
"label" : "Label",
"attributes": []
}
}
}}
<div class="container-fluid my-1">
<div class="row">
<div class="d-flex">
<div>
{{#urlselect}}
{{>core/url_select}}
{{/urlselect}}
</div>
<div class="pl-2">
{{#addentrybutton}}
{{>core/single_button}}
{{/addentrybutton}}
</div>
</div>
<div class="ml-auto d-flex">
<div>
{{#importentriesbutton}}
{{>core/single_button}}
{{/importentriesbutton}}
</div>
<div class="pl-2">
{{#exportentriesbutton}}
{{>core/single_button}}
{{/exportentriesbutton}}
</div>
</div>
</div>
</div>

View File

@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2021052500; // The current module version (Date: YYYYMMDDXX).
$plugin->version = 2021052501; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2021052500; // Requires this Moodle version.
$plugin->component = 'mod_data'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;

View File

@ -22,360 +22,353 @@
// //
///////////////////////////////////////////////////////////////////////////
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/mod/data/locallib.php');
require_once($CFG->libdir . '/rsslib.php');
require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/mod/data/locallib.php');
require_once($CFG->libdir . '/rsslib.php');
/// One of these is necessary!
$id = optional_param('id', 0, PARAM_INT); // course module id
$d = optional_param('d', 0, PARAM_INT); // database id
$rid = optional_param('rid', 0, PARAM_INT); //record id
$mode = optional_param('mode', '', PARAM_ALPHA); // Force the browse mode ('single')
$filter = optional_param('filter', 0, PARAM_BOOL);
// search filter will only be applied when $filter is true
$id = optional_param('id', 0, PARAM_INT); // course module id
$d = optional_param('d', 0, PARAM_INT); // database id
$rid = optional_param('rid', 0, PARAM_INT); //record id
$mode = optional_param('mode', '', PARAM_ALPHA); // Force the browse mode ('single')
$filter = optional_param('filter', 0, PARAM_BOOL);
// search filter will only be applied when $filter is true
$edit = optional_param('edit', -1, PARAM_BOOL);
$page = optional_param('page', 0, PARAM_INT);
$edit = optional_param('edit', -1, PARAM_BOOL);
$page = optional_param('page', 0, PARAM_INT);
/// These can be added to perform an action on a record
$approve = optional_param('approve', 0, PARAM_INT); //approval recordid
$disapprove = optional_param('disapprove', 0, PARAM_INT); // disapproval recordid
$delete = optional_param('delete', 0, PARAM_INT); //delete recordid
$multidelete = optional_param_array('delcheck', null, PARAM_INT);
$serialdelete = optional_param('serialdelete', null, PARAM_RAW);
$approve = optional_param('approve', 0, PARAM_INT); //approval recordid
$disapprove = optional_param('disapprove', 0, PARAM_INT); // disapproval recordid
$delete = optional_param('delete', 0, PARAM_INT); //delete recordid
$multidelete = optional_param_array('delcheck', null, PARAM_INT);
$serialdelete = optional_param('serialdelete', null, PARAM_RAW);
if ($id) {
if (! $cm = get_coursemodule_from_id('data', $id)) {
print_error('invalidcoursemodule');
}
if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
print_error('coursemisconf');
}
if (! $data = $DB->get_record('data', array('id'=>$cm->instance))) {
print_error('invalidcoursemodule');
}
$record = NULL;
} else if ($rid) {
if (! $record = $DB->get_record('data_records', array('id'=>$rid))) {
print_error('invalidrecord', 'data');
}
if (! $data = $DB->get_record('data', array('id'=>$record->dataid))) {
print_error('invalidid', 'data');
}
if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
print_error('coursemisconf');
}
if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
print_error('invalidcoursemodule');
}
} else { // We must have $d
if (! $data = $DB->get_record('data', array('id'=>$d))) {
print_error('invalidid', 'data');
}
if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
print_error('coursemisconf');
}
if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
print_error('invalidcoursemodule');
}
$record = NULL;
if ($id) {
if (! $cm = get_coursemodule_from_id('data', $id)) {
print_error('invalidcoursemodule');
}
$cm = cm_info::create($cm);
require_course_login($course, true, $cm);
if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
print_error('coursemisconf');
}
if (! $data = $DB->get_record('data', array('id'=>$cm->instance))) {
print_error('invalidcoursemodule');
}
$record = NULL;
require_once($CFG->dirroot . '/comment/lib.php');
comment::init();
} else if ($rid) {
if (! $record = $DB->get_record('data_records', array('id'=>$rid))) {
print_error('invalidrecord', 'data');
}
if (! $data = $DB->get_record('data', array('id'=>$record->dataid))) {
print_error('invalidid', 'data');
}
if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
print_error('coursemisconf');
}
if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
print_error('invalidcoursemodule');
}
} else { // We must have $d
if (! $data = $DB->get_record('data', array('id'=>$d))) {
print_error('invalidid', 'data');
}
if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
print_error('coursemisconf');
}
if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
print_error('invalidcoursemodule');
}
$record = NULL;
}
$cm = cm_info::create($cm);
require_course_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/data:viewentry', $context);
require_once($CFG->dirroot . '/comment/lib.php');
comment::init();
$context = context_module::instance($cm->id);
require_capability('mod/data:viewentry', $context);
/// If we have an empty Database then redirect because this page is useless without data
if (has_capability('mod/data:managetemplates', $context)) {
if (!$DB->record_exists('data_fields', array('dataid'=>$data->id))) { // Brand new database!
redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id); // Redirect to field entry
}
if (has_capability('mod/data:managetemplates', $context)) {
if (!$DB->record_exists('data_fields', array('dataid'=>$data->id))) { // Brand new database!
redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id); // Redirect to field entry
}
}
/// Check further parameters that set browsing preferences
if (!isset($SESSION->dataprefs)) {
$SESSION->dataprefs = array();
}
if (!isset($SESSION->dataprefs[$data->id])) {
$SESSION->dataprefs[$data->id] = array();
$SESSION->dataprefs[$data->id]['search'] = '';
if (!isset($SESSION->dataprefs)) {
$SESSION->dataprefs = array();
}
if (!isset($SESSION->dataprefs[$data->id])) {
$SESSION->dataprefs[$data->id] = array();
$SESSION->dataprefs[$data->id]['search'] = '';
$SESSION->dataprefs[$data->id]['search_array'] = array();
$SESSION->dataprefs[$data->id]['sort'] = $data->defaultsort;
$SESSION->dataprefs[$data->id]['advanced'] = 0;
$SESSION->dataprefs[$data->id]['order'] = ($data->defaultsortdir == 0) ? 'ASC' : 'DESC';
}
// reset advanced form
if (!is_null(optional_param('resetadv', null, PARAM_RAW))) {
$SESSION->dataprefs[$data->id]['search_array'] = array();
// we need the redirect to cleanup the form state properly
redirect("view.php?id=$cm->id&amp;mode=$mode&amp;search=&amp;advanced=1");
}
$advanced = optional_param('advanced', -1, PARAM_INT);
if ($advanced == -1) {
$advanced = $SESSION->dataprefs[$data->id]['advanced'];
} else {
if (!$advanced) {
// explicitly switched to normal mode - discard all advanced search settings
$SESSION->dataprefs[$data->id]['search_array'] = array();
$SESSION->dataprefs[$data->id]['sort'] = $data->defaultsort;
$SESSION->dataprefs[$data->id]['advanced'] = 0;
$SESSION->dataprefs[$data->id]['order'] = ($data->defaultsortdir == 0) ? 'ASC' : 'DESC';
}
$SESSION->dataprefs[$data->id]['advanced'] = $advanced;
}
$search_array = $SESSION->dataprefs[$data->id]['search_array'];
if (!empty($advanced)) {
$search = '';
//Added to ammend paging error. This error would occur when attempting to go from one page of advanced
//search results to another. All fields were reset in the page transfer, and there was no way of determining
//whether or not the user reset them. This would cause a blank search to execute whenever the user attempted
//to see any page of results past the first.
//This fix works as follows:
//$paging flag is set to false when page 0 of the advanced search results is viewed for the first time.
//Viewing any page of results after page 0 passes the false $paging flag though the URL (see line 523) and the
//execution falls through to the second condition below, allowing paging to be set to true.
//Paging remains true and keeps getting passed though the URL until a new search is performed
//(even if page 0 is revisited).
//A false $paging flag generates advanced search results based on the fields input by the user.
//A true $paging flag generates davanced search results from the $SESSION global.
$paging = optional_param('paging', NULL, PARAM_BOOL);
if($page == 0 && !isset($paging)) {
$paging = false;
}
else {
$paging = true;
}
// reset advanced form
if (!is_null(optional_param('resetadv', null, PARAM_RAW))) {
$SESSION->dataprefs[$data->id]['search_array'] = array();
// we need the redirect to cleanup the form state properly
redirect("view.php?id=$cm->id&amp;mode=$mode&amp;search=&amp;advanced=1");
}
// Now build the advanced search array.
list($search_array, $search) = data_build_search_array($data, $paging, $search_array);
$SESSION->dataprefs[$data->id]['search_array'] = $search_array; // Make it sticky.
$advanced = optional_param('advanced', -1, PARAM_INT);
if ($advanced == -1) {
$advanced = $SESSION->dataprefs[$data->id]['advanced'];
} else {
if (!$advanced) {
// explicitly switched to normal mode - discard all advanced search settings
$SESSION->dataprefs[$data->id]['search_array'] = array();
}
$SESSION->dataprefs[$data->id]['advanced'] = $advanced;
}
} else {
$search = optional_param('search', $SESSION->dataprefs[$data->id]['search'], PARAM_NOTAGS);
//Paging variable not used for standard search. Set it to null.
$paging = NULL;
}
$search_array = $SESSION->dataprefs[$data->id]['search_array'];
// Disable search filters if $filter is not true:
if (! $filter) {
$search = '';
}
if (!empty($advanced)) {
$search = '';
$SESSION->dataprefs[$data->id]['search'] = $search; // Make it sticky
//Added to ammend paging error. This error would occur when attempting to go from one page of advanced
//search results to another. All fields were reset in the page transfer, and there was no way of determining
//whether or not the user reset them. This would cause a blank search to execute whenever the user attempted
//to see any page of results past the first.
//This fix works as follows:
//$paging flag is set to false when page 0 of the advanced search results is viewed for the first time.
//Viewing any page of results after page 0 passes the false $paging flag though the URL (see line 523) and the
//execution falls through to the second condition below, allowing paging to be set to true.
//Paging remains true and keeps getting passed though the URL until a new search is performed
//(even if page 0 is revisited).
//A false $paging flag generates advanced search results based on the fields input by the user.
//A true $paging flag generates davanced search results from the $SESSION global.
$sort = optional_param('sort', $SESSION->dataprefs[$data->id]['sort'], PARAM_INT);
$SESSION->dataprefs[$data->id]['sort'] = $sort; // Make it sticky
$paging = optional_param('paging', NULL, PARAM_BOOL);
if($page == 0 && !isset($paging)) {
$paging = false;
}
else {
$paging = true;
}
// Now build the advanced search array.
list($search_array, $search) = data_build_search_array($data, $paging, $search_array);
$SESSION->dataprefs[$data->id]['search_array'] = $search_array; // Make it sticky.
} else {
$search = optional_param('search', $SESSION->dataprefs[$data->id]['search'], PARAM_NOTAGS);
//Paging variable not used for standard search. Set it to null.
$paging = NULL;
}
// Disable search filters if $filter is not true:
if (! $filter) {
$search = '';
}
$SESSION->dataprefs[$data->id]['search'] = $search; // Make it sticky
$sort = optional_param('sort', $SESSION->dataprefs[$data->id]['sort'], PARAM_INT);
$SESSION->dataprefs[$data->id]['sort'] = $sort; // Make it sticky
$order = (optional_param('order', $SESSION->dataprefs[$data->id]['order'], PARAM_ALPHA) == 'ASC') ? 'ASC': 'DESC';
$SESSION->dataprefs[$data->id]['order'] = $order; // Make it sticky
$order = (optional_param('order', $SESSION->dataprefs[$data->id]['order'], PARAM_ALPHA) == 'ASC') ? 'ASC': 'DESC';
$SESSION->dataprefs[$data->id]['order'] = $order; // Make it sticky
$oldperpage = get_user_preferences('data_perpage_'.$data->id, 10);
$perpage = optional_param('perpage', $oldperpage, PARAM_INT);
$oldperpage = get_user_preferences('data_perpage_'.$data->id, 10);
$perpage = optional_param('perpage', $oldperpage, PARAM_INT);
if ($perpage < 2) {
$perpage = 2;
}
if ($perpage != $oldperpage) {
set_user_preference('data_perpage_'.$data->id, $perpage);
}
if ($perpage < 2) {
$perpage = 2;
}
if ($perpage != $oldperpage) {
set_user_preference('data_perpage_'.$data->id, $perpage);
}
// Completion and trigger events.
data_view($data, $course, $cm, $context);
// Completion and trigger events.
data_view($data, $course, $cm, $context);
$urlparams = array('d' => $data->id);
if ($record) {
$urlparams['rid'] = $record->id;
}
if ($page) {
$urlparams['page'] = $page;
}
if ($mode) {
$urlparams['mode'] = $mode;
}
if ($filter) {
$urlparams['filter'] = $filter;
}
// Initialize $PAGE, compute blocks
$PAGE->set_url('/mod/data/view.php', $urlparams);
$urlparams = array('d' => $data->id);
if ($record) {
$urlparams['rid'] = $record->id;
}
if ($mode) {
$urlparams['mode'] = $mode;
}
if ($page) {
$urlparams['page'] = $page;
}
if ($filter) {
$urlparams['filter'] = $filter;
}
$pageurl = new moodle_url('/mod/data/view.php', $urlparams);
if (($edit != -1) and $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
// Initialize $PAGE, compute blocks.
$PAGE->set_url($pageurl);
$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
if (($edit != -1) and $PAGE->user_allowed_editing()) {
$USER->editing = $edit;
}
$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
/// RSS and CSS and JS meta
$meta = '';
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
$rsstitle = $courseshortname . ': ' . format_string($data->name);
rss_add_http_header($context, 'mod_data', $data, $rsstitle);
}
if ($data->csstemplate) {
$PAGE->requires->css('/mod/data/css.php?d='.$data->id);
}
if ($data->jstemplate) {
$PAGE->requires->js('/mod/data/js.php?d='.$data->id, true);
}
$meta = '';
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
$rsstitle = $courseshortname . ': ' . format_string($data->name);
rss_add_http_header($context, 'mod_data', $data, $rsstitle);
}
if ($data->csstemplate) {
$PAGE->requires->css('/mod/data/css.php?d='.$data->id);
}
if ($data->jstemplate) {
$PAGE->requires->js('/mod/data/js.php?d='.$data->id, true);
}
/// Print the page header
// Note: MDL-19010 there will be further changes to printing header and blocks.
// The code will be much nicer than this eventually.
$title = $courseshortname.': ' . format_string($data->name);
// Note: MDL-19010 there will be further changes to printing header and blocks.
// The code will be much nicer than this eventually.
$title = $courseshortname.': ' . format_string($data->name);
if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
// Change URL parameter and block display string value depending on whether editing is enabled or not
if ($PAGE->user_is_editing()) {
$urlediting = 'off';
$strediting = get_string('blockseditoff');
} else {
$urlediting = 'on';
$strediting = get_string('blocksediton');
}
$url = new moodle_url($CFG->wwwroot.'/mod/data/view.php', array('id' => $cm->id, 'edit' => $urlediting));
$PAGE->set_button($OUTPUT->single_button($url, $strediting));
if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
// Change URL parameter and block display string value depending on whether editing is enabled or not
if ($PAGE->user_is_editing()) {
$urlediting = 'off';
$strediting = get_string('blockseditoff');
} else {
$urlediting = 'on';
$strediting = get_string('blocksediton');
}
$url = new moodle_url($CFG->wwwroot.'/mod/data/view.php', array('id' => $cm->id, 'edit' => $urlediting));
$PAGE->set_button($OUTPUT->single_button($url, $strediting));
}
if ($mode == 'asearch') {
$PAGE->navbar->add(get_string('search'));
}
if ($mode == 'asearch') {
$PAGE->navbar->add(get_string('search'));
}
$PAGE->force_settings_menu();
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
$PAGE->force_settings_menu(true);
echo $OUTPUT->header();
// Check to see if groups are being used here.
// We need the most up to date current group value. Make sure it is updated at this point.
$currentgroup = groups_get_activity_group($cm, true);
$groupmode = groups_get_activity_groupmode($cm);
$canmanageentries = has_capability('mod/data:manageentries', $context);
// Check to see if groups are being used here.
// We need the most up to date current group value. Make sure it is updated at this point.
$currentgroup = groups_get_activity_group($cm, true);
$groupmode = groups_get_activity_groupmode($cm);
$canmanageentries = has_capability('mod/data:manageentries', $context);
echo $OUTPUT->header();
// Detect entries not approved yet and show hint instead of not found error.
if ($record and !data_can_view_record($data, $record, $currentgroup, $canmanageentries)) {
print_error('notapproved', 'data');
}
// Detect entries not approved yet and show hint instead of not found error.
if ($record and !data_can_view_record($data, $record, $currentgroup, $canmanageentries)) {
print_error('notapproved', 'data');
}
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading(format_string($data->name), 2);
}
// Render the activity information.
$completiondetails = \core_completion\cm_completion_details::get_instance($cm, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id);
echo $OUTPUT->activity_information($cm, $completiondetails, $activitydates);
// Render the activity information.
$completiondetails = \core_completion\cm_completion_details::get_instance($cm, $USER->id);
$activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id);
echo $OUTPUT->activity_information($cm, $completiondetails, $activitydates);
// Do we need to show a link to the RSS feed for the records?
//this links has been Settings (database activity administration) block
/*if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
echo '<div style="float:right;">';
rss_print_link($context->id, $USER->id, 'mod_data', $data->id, get_string('rsstype'));
echo '</div>';
echo '<div style="clear:both;"></div>';
}*/
// Do we need to show a link to the RSS feed for the records?
//this links has been Settings (database activity administration) block
/*if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
echo '<div style="float:right;">';
rss_print_link($context->id, $USER->id, 'mod_data', $data->id, get_string('rsstype'));
echo '</div>';
echo '<div style="clear:both;"></div>';
}*/
if ($data->intro and empty($page) and empty($record) and $mode != 'single') {
$options = new stdClass();
$options->noclean = true;
}
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
if ($data->intro and empty($page) and empty($record) and $mode != 'single') {
$options = new stdClass();
$options->noclean = true;
}
echo $OUTPUT->box(format_module_intro('data', $data, $cm->id), 'generalbox', 'intro');
$returnurl = $CFG->wwwroot . '/mod/data/view.php?d='.$data->id.'&amp;search='.s($search).'&amp;sort='.s($sort).'&amp;order='.s($order).'&amp;';
groups_print_activity_menu($cm, $returnurl);
$returnurl = $CFG->wwwroot . '/mod/data/view.php?d='.$data->id.'&amp;search='.s($search).'&amp;sort='.s($sort).'&amp;order='.s($order).'&amp;';
groups_print_activity_menu($cm, $returnurl);
/// Delete any requested records
if ($delete && confirm_sesskey() && (data_user_can_manage_entry($delete, $data, $context))) {
if ($confirm = optional_param('confirm',0,PARAM_INT)) {
if (data_delete_record($delete, $data, $course->id, $cm->id)) {
echo $OUTPUT->notification(get_string('recorddeleted','data'), 'notifysuccess');
if ($delete && confirm_sesskey() && (data_user_can_manage_entry($delete, $data, $context))) {
if ($confirm = optional_param('confirm',0,PARAM_INT)) {
if (data_delete_record($delete, $data, $course->id, $cm->id)) {
echo $OUTPUT->notification(get_string('recorddeleted','data'), 'notifysuccess');
}
} else { // Print a confirmation page
$userfieldsapi = \core_user\fields::for_userpic()->excluding('id');
$allnamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$dbparams = array($delete);
if ($deleterecord = $DB->get_record_sql("SELECT dr.*, $allnamefields
FROM {data_records} dr
JOIN {user} u ON dr.userid = u.id
WHERE dr.id = ?", $dbparams, MUST_EXIST)) { // Need to check this is valid.
if ($deleterecord->dataid == $data->id) { // Must be from this database
$deletebutton = new single_button(new moodle_url('/mod/data/view.php?d='.$data->id.'&delete='.$delete.'&confirm=1'), get_string('delete'), 'post');
echo $OUTPUT->confirm(get_string('confirmdeleterecord','data'),
$deletebutton, 'view.php?d='.$data->id);
$records[] = $deleterecord;
echo data_print_template('singletemplate', $records, $data, '', 0, true);
echo $OUTPUT->footer();
exit;
}
} else { // Print a confirmation page
}
}
}
// Multi-delete.
if ($serialdelete) {
$multidelete = json_decode($serialdelete);
}
if ($multidelete && confirm_sesskey() && $canmanageentries) {
if ($confirm = optional_param('confirm', 0, PARAM_INT)) {
foreach ($multidelete as $value) {
data_delete_record($value, $data, $course->id, $cm->id);
}
} else {
$validrecords = array();
$recordids = array();
foreach ($multidelete as $value) {
$userfieldsapi = \core_user\fields::for_userpic()->excluding('id');
$allnamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$dbparams = array($delete);
$dbparams = array('id' => $value);
if ($deleterecord = $DB->get_record_sql("SELECT dr.*, $allnamefields
FROM {data_records} dr
JOIN {user} u ON dr.userid = u.id
WHERE dr.id = ?", $dbparams, MUST_EXIST)) { // Need to check this is valid.
if ($deleterecord->dataid == $data->id) { // Must be from this database
$deletebutton = new single_button(new moodle_url('/mod/data/view.php?d='.$data->id.'&delete='.$delete.'&confirm=1'), get_string('delete'), 'post');
echo $OUTPUT->confirm(get_string('confirmdeleterecord','data'),
$deletebutton, 'view.php?d='.$data->id);
$records[] = $deleterecord;
echo data_print_template('singletemplate', $records, $data, '', 0, true);
echo $OUTPUT->footer();
exit;
JOIN {user} u ON dr.userid = u.id
WHERE dr.id = ?", $dbparams)) { // Need to check this is valid.
if ($deleterecord->dataid == $data->id) { // Must be from this database.
$validrecords[] = $deleterecord;
$recordids[] = $deleterecord->id;
}
}
}
$serialiseddata = json_encode($recordids);
$submitactions = array('d' => $data->id, 'sesskey' => sesskey(), 'confirm' => '1', 'serialdelete' => $serialiseddata);
$action = new moodle_url('/mod/data/view.php', $submitactions);
$cancelurl = new moodle_url('/mod/data/view.php', array('d' => $data->id));
$deletebutton = new single_button($action, get_string('delete'));
echo $OUTPUT->confirm(get_string('confirmdeleterecords', 'data'), $deletebutton, $cancelurl);
echo data_print_template('listtemplate', $validrecords, $data, '', 0, false);
echo $OUTPUT->footer();
exit;
}
}
// Multi-delete.
if ($serialdelete) {
$multidelete = json_decode($serialdelete);
}
if ($multidelete && confirm_sesskey() && $canmanageentries) {
if ($confirm = optional_param('confirm', 0, PARAM_INT)) {
foreach ($multidelete as $value) {
data_delete_record($value, $data, $course->id, $cm->id);
}
} else {
$validrecords = array();
$recordids = array();
foreach ($multidelete as $value) {
$userfieldsapi = \core_user\fields::for_userpic()->excluding('id');
$allnamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$dbparams = array('id' => $value);
if ($deleterecord = $DB->get_record_sql("SELECT dr.*, $allnamefields
FROM {data_records} dr
JOIN {user} u ON dr.userid = u.id
WHERE dr.id = ?", $dbparams)) { // Need to check this is valid.
if ($deleterecord->dataid == $data->id) { // Must be from this database.
$validrecords[] = $deleterecord;
$recordids[] = $deleterecord->id;
}
}
}
$serialiseddata = json_encode($recordids);
$submitactions = array('d' => $data->id, 'sesskey' => sesskey(), 'confirm' => '1', 'serialdelete' => $serialiseddata);
$action = new moodle_url('/mod/data/view.php', $submitactions);
$cancelurl = new moodle_url('/mod/data/view.php', array('d' => $data->id));
$deletebutton = new single_button($action, get_string('delete'));
echo $OUTPUT->confirm(get_string('confirmdeleterecords', 'data'), $deletebutton, $cancelurl);
echo data_print_template('listtemplate', $validrecords, $data, '', 0, false);
echo $OUTPUT->footer();
exit;
}
}
// If data activity closed dont let students in.
// No need to display warnings because activity dates are displayed at the top of the page.
list($showactivity, $warnings) = data_get_time_availability_status($data, $canmanageentries);
// If data activity closed dont let students in.
// No need to display warnings because activity dates are displayed at the top of the page.
list($showactivity, $warnings) = data_get_time_availability_status($data, $canmanageentries);
if ($showactivity) {
// Print the tabs
if ($record or $mode == 'single') {
$currenttab = 'single';
} elseif($mode == 'asearch') {
$currenttab = 'asearch';
}
else {
$currenttab = 'list';
}
include('tabs.php');
if ($mode == 'asearch') {
$maxcount = 0;
@ -415,6 +408,10 @@ if ($showactivity) {
// Search for entries.
list($records, $maxcount, $totalcount, $page, $nowperpage, $sort, $mode) =
data_search_entries($data, $cm, $context, $mode, $currentgroup, $search, $sort, $order, $page, $perpage, $advanced, $search_array, $record);
$hasrecords = !empty($records);
$actionbar = new \mod_data\output\action_bar($data->id, $pageurl);
echo $actionbar->get_view_action_bar($hasrecords);
// Advanced search form doesn't make sense for single (redirects list view).
if ($maxcount && $mode != 'single') {

View File

@ -935,10 +935,6 @@ $grading-content-show-content-button-padding-left: calc(#{map-get($spacers, 2) *
width: auto;
}
.path-mod-data form {
margin-top: 10px;
}
.template_heading {
margin-top: 10px;
}

View File

@ -17819,9 +17819,6 @@ select {
#page-mod-data-view #singleimage {
width: auto; }
.path-mod-data form {
margin-top: 10px; }
.template_heading {
margin-top: 10px; }

View File

@ -17819,9 +17819,6 @@ select {
#page-mod-data-view #singleimage {
width: auto; }
.path-mod-data form {
margin-top: 10px; }
.template_heading {
margin-top: 10px; }