mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-78909 mod_lti: Support coursevisibility override for courses
This commit is contained in:
parent
b4c6ed3650
commit
f9b1bac756
2
mod/lti/amd/build/course_tools_list.min.js
vendored
2
mod/lti/amd/build/course_tools_list.min.js
vendored
@ -1,3 +1,3 @@
|
||||
define("mod_lti/course_tools_list",["exports","core/notification","core/pending","core/ajax","core/toast","core/str","core_table/dynamic","core_table/local/dynamic/selectors"],(function(_exports,_notification,_pending,_ajax,_toast,_str,_dynamic,Selectors){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_ajax=_interopRequireDefault(_ajax),Selectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Selectors);_exports.init=()=>{document.addEventListener("click",(event=>{const courseToolDelete=event.target.closest('[data-action="course-tool-delete"]');if(courseToolDelete){event.preventDefault();const deleteBodyStringId=courseToolDelete.dataset.courseToolUsage>0?"deletecoursetoolwithusageconfirm":"deletecoursetoolconfirm",requiredStrings=[{key:"deletecoursetool",component:"mod_lti",param:courseToolDelete.dataset.courseToolName},{key:deleteBodyStringId,component:"mod_lti",param:courseToolDelete.dataset.courseToolName},{key:"delete",component:"core",param:courseToolDelete.dataset.courseToolName},{key:"coursetooldeleted",component:"mod_lti",param:courseToolDelete.dataset.courseToolName}],triggerElement=courseToolDelete.closest(".dropdown").querySelector(".dropdown-toggle");(0,_str.getStrings)(requiredStrings).then((_ref=>{let[modalTitle,modalBody,deleteLabel]=_ref;return _notification.default.deleteCancelPromise(modalTitle,modalBody,deleteLabel,{triggerElement:triggerElement})})).then((()=>{const pendingPromise=new _pending.default("mod_lti/course_tools:delete"),request={methodname:"mod_lti_delete_course_tool_type",args:{tooltypeid:courseToolDelete.dataset.courseToolId}};return _ajax.default.call([request])[0].then((0,_toast.add)((0,_str.getString)("coursetooldeleted","mod_lti",courseToolDelete.dataset.courseToolName))).then((()=>{const tableRoot=triggerElement.closest(Selectors.main.region);return(0,_dynamic.refreshTableContent)(tableRoot)})).then(pendingPromise.resolve).catch(_notification.default.exception)})).catch((()=>{}))}}))}}));
|
||||
define("mod_lti/course_tools_list",["exports","core/notification","core/pending","core/ajax","core/toast","core/str","core_table/dynamic","core_table/local/dynamic/selectors","./repository"],(function(_exports,_notification,_pending,_ajax,_toast,_str,_dynamic,Selectors,_repository){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending),_ajax=_interopRequireDefault(_ajax),Selectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Selectors);_exports.init=()=>{document.addEventListener("click",(event=>{const courseToolDelete=event.target.closest('[data-action="course-tool-delete"]');if(courseToolDelete){event.preventDefault();const deleteBodyStringId=courseToolDelete.dataset.courseToolUsage>0?"deletecoursetoolwithusageconfirm":"deletecoursetoolconfirm",requiredStrings=[{key:"deletecoursetool",component:"mod_lti",param:courseToolDelete.dataset.courseToolName},{key:deleteBodyStringId,component:"mod_lti",param:courseToolDelete.dataset.courseToolName},{key:"delete",component:"core",param:courseToolDelete.dataset.courseToolName},{key:"coursetooldeleted",component:"mod_lti",param:courseToolDelete.dataset.courseToolName}],triggerElement=courseToolDelete.closest(".dropdown").querySelector(".dropdown-toggle");(0,_str.getStrings)(requiredStrings).then((_ref=>{let[modalTitle,modalBody,deleteLabel]=_ref;return _notification.default.deleteCancelPromise(modalTitle,modalBody,deleteLabel,{triggerElement:triggerElement})})).then((()=>{const pendingPromise=new _pending.default("mod_lti/course_tools:delete"),request={methodname:"mod_lti_delete_course_tool_type",args:{tooltypeid:courseToolDelete.dataset.courseToolId}};return _ajax.default.call([request])[0].then((0,_toast.add)((0,_str.getString)("coursetooldeleted","mod_lti",courseToolDelete.dataset.courseToolName))).then((()=>{const tableRoot=triggerElement.closest(Selectors.main.region);return(0,_dynamic.refreshTableContent)(tableRoot)})).then(pendingPromise.resolve).catch(_notification.default.exception)})).catch((()=>{}))}const courseShowInActivityChooser=event.target.closest('[data-action="showinactivitychooser-toggle"]');if(courseShowInActivityChooser){const showInActivityChooserStateToggle="0"===courseShowInActivityChooser.dataset.state?1:0;return(0,_repository.toggleShowInActivityChooser)(courseShowInActivityChooser.dataset.id,courseShowInActivityChooser.dataset.courseid,showInActivityChooserStateToggle)}}))}}));
|
||||
|
||||
//# sourceMappingURL=course_tools_list.min.js.map
|
File diff suppressed because one or more lines are too long
10
mod/lti/amd/build/repository.min.js
vendored
Normal file
10
mod/lti/amd/build/repository.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
define("mod_lti/repository",["exports","core/ajax"],(function(_exports,_ajax){var obj;
|
||||
/**
|
||||
* Module to handle AJAX interactions.
|
||||
*
|
||||
* @module mod_lti/repository
|
||||
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.toggleShowInActivityChooser=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.toggleShowInActivityChooser=(tooltypeid,courseid,coursevisible)=>_ajax.default.call([{methodname:"mod_lti_toggle_showinactivitychooser",args:{tooltypeid:tooltypeid,courseid:courseid,coursevisible:coursevisible}}])[0]}));
|
||||
|
||||
//# sourceMappingURL=repository.min.js.map
|
1
mod/lti/amd/build/repository.min.js.map
Normal file
1
mod/lti/amd/build/repository.min.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"repository.min.js","sources":["../src/repository.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Module to handle AJAX interactions.\n *\n * @module mod_lti/repository\n * @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Toggle coursevisible of a tool\n *\n * @param {Number} tooltypeid Too type id\n * @param {Number} courseid Course ID\n * @param {Number} coursevisible coursevisible state\n * @return {Promise}\n */\nexport const toggleShowInActivityChooser = (\n tooltypeid,\n courseid,\n coursevisible,\n) => Ajax.call([{\n methodname: 'mod_lti_toggle_showinactivitychooser',\n args: {\n tooltypeid,\n courseid,\n coursevisible,\n },\n}])[0];\n"],"names":["tooltypeid","courseid","coursevisible","Ajax","call","methodname","args"],"mappings":";;;;;;;kMAiC2C,CACvCA,WACAC,SACAC,gBACCC,cAAKC,KAAK,CAAC,CACZC,WAAY,uCACZC,KAAM,CACFN,WAAAA,WACAC,SAAAA,SACAC,cAAAA,kBAEJ"}
|
@ -30,6 +30,7 @@ import {add as addToast} from 'core/toast';
|
||||
import {getString, getStrings} from 'core/str';
|
||||
import {refreshTableContent} from 'core_table/dynamic';
|
||||
import * as Selectors from 'core_table/local/dynamic/selectors';
|
||||
import {toggleShowInActivityChooser} from "./repository";
|
||||
|
||||
/**
|
||||
* Initialise module.
|
||||
@ -78,5 +79,15 @@ export const init = () => {
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
const courseShowInActivityChooser = event.target.closest('[data-action="showinactivitychooser-toggle"]');
|
||||
if (courseShowInActivityChooser) {
|
||||
const showInActivityChooserStateToggle = courseShowInActivityChooser.dataset.state === "0" ? 1 : 0;
|
||||
return toggleShowInActivityChooser(
|
||||
courseShowInActivityChooser.dataset.id,
|
||||
courseShowInActivityChooser.dataset.courseid,
|
||||
showInActivityChooserStateToggle,
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
45
mod/lti/amd/src/repository.js
Normal file
45
mod/lti/amd/src/repository.js
Normal file
@ -0,0 +1,45 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Module to handle AJAX interactions.
|
||||
*
|
||||
* @module mod_lti/repository
|
||||
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import Ajax from 'core/ajax';
|
||||
|
||||
/**
|
||||
* Toggle coursevisible of a tool
|
||||
*
|
||||
* @param {Number} tooltypeid Too type id
|
||||
* @param {Number} courseid Course ID
|
||||
* @param {Number} coursevisible coursevisible state
|
||||
* @return {Promise}
|
||||
*/
|
||||
export const toggleShowInActivityChooser = (
|
||||
tooltypeid,
|
||||
courseid,
|
||||
coursevisible,
|
||||
) => Ajax.call([{
|
||||
methodname: 'mod_lti_toggle_showinactivitychooser',
|
||||
args: {
|
||||
tooltypeid,
|
||||
courseid,
|
||||
coursevisible,
|
||||
},
|
||||
}])[0];
|
@ -146,6 +146,12 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
|
||||
'state'
|
||||
));
|
||||
|
||||
$lticoursevisible = new backup_nested_element('lticoursevisible', ['id'], [
|
||||
'typeid',
|
||||
'courseid',
|
||||
'coursevisible',
|
||||
]);
|
||||
|
||||
// Build the tree
|
||||
$lti->add_child($ltitype);
|
||||
$ltitype->add_child($ltitypesconfigs);
|
||||
@ -156,6 +162,7 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
|
||||
$ltitoolsettings->add_child($ltitoolsetting);
|
||||
$lti->add_child($ltisubmissions);
|
||||
$ltisubmissions->add_child($ltisubmission);
|
||||
$lti->add_child($lticoursevisible);
|
||||
|
||||
// Define sources.
|
||||
$ltirecord = $DB->get_record('lti', ['id' => $this->task->get_activityid()]);
|
||||
@ -193,6 +200,9 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
|
||||
$ltisubmission->set_source_table('lti_submission', array('ltiid' => backup::VAR_ACTIVITYID));
|
||||
}
|
||||
|
||||
$lticoursevisibledata = $this->retrieve_lti_coursevisible($ltirecord);
|
||||
$lticoursevisible->set_source_array($lticoursevisibledata ? [$lticoursevisibledata] : []);
|
||||
|
||||
// Define id annotations
|
||||
$ltitype->annotate_ids('user', 'createdby');
|
||||
$ltitype->annotate_ids('course', 'course');
|
||||
@ -238,4 +248,18 @@ class backup_lti_activity_structure_step extends backup_activity_structure_step
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a record from {lti_coursevisible} table associated with the current type
|
||||
*
|
||||
* @param stdClass $ltirecord record from {lti} table
|
||||
* @return mixed
|
||||
*/
|
||||
protected function retrieve_lti_coursevisible(stdClass $ltirecord): mixed {
|
||||
global $DB;
|
||||
if (!$ltirecord->typeid) {
|
||||
return null;
|
||||
}
|
||||
return $DB->get_record('lti_coursevisible', ['typeid' => $ltirecord->typeid, 'courseid' => $ltirecord->course]);
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste
|
||||
$paths[] = $submission;
|
||||
}
|
||||
|
||||
$paths[] = new restore_path_element('lticoursevisible', '/activity/lti/lticoursevisible');
|
||||
|
||||
// Add support for subplugin structures.
|
||||
$this->add_subplugin_structure('ltisource', $lti);
|
||||
$this->add_subplugin_structure('ltiservice', $lti);
|
||||
@ -149,6 +151,23 @@ class restore_lti_activity_structure_step extends restore_activity_structure_ste
|
||||
$DB->update_record('lti', ['id' => $this->get_new_parentid('lti'), 'typeid' => $ltitypeid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an lti coursevisible restore
|
||||
* @param mixed $data The data from backup XML file
|
||||
* @return void
|
||||
*/
|
||||
protected function process_lticoursevisible($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$data->typeid = $this->get_new_parentid('ltitype');
|
||||
$data->courseid = $this->get_courseid();
|
||||
|
||||
if ($data->typeid) {
|
||||
$DB->insert_record('lti_coursevisible', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find existing record in lti_type
|
||||
* @param stdClass $data
|
||||
|
116
mod/lti/classes/external/toggle_showinactivitychooser.php
vendored
Normal file
116
mod/lti/classes/external/toggle_showinactivitychooser.php
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
<?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_lti\external;
|
||||
|
||||
use core_external\external_api;
|
||||
use core_external\external_function_parameters;
|
||||
use core_external\external_value;
|
||||
use mod_lti\local\ltiopenid\registration_helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/lti/locallib.php');
|
||||
|
||||
/**
|
||||
* External function to toggle showinactivitychooser setting.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class toggle_showinactivitychooser extends external_api {
|
||||
|
||||
/**
|
||||
* Get parameter definition.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function execute_parameters(): external_function_parameters {
|
||||
return new external_function_parameters([
|
||||
'tooltypeid' => new external_value(PARAM_INT, 'Tool type ID'),
|
||||
'courseid' => new external_value(PARAM_INT, 'Course ID'),
|
||||
'coursevisible' => new external_value(PARAM_BOOL, 'Show in activity chooser'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles showinactivitychooser setting.
|
||||
*
|
||||
* @param int $tooltypeid the id of the course external tool type.
|
||||
* @param int $courseid the id of the course we are in.
|
||||
* @param bool $showinactivitychooser Show in activity chooser setting.
|
||||
* @return bool true
|
||||
*/
|
||||
public static function execute(int $tooltypeid, int $courseid, bool $showinactivitychooser): bool {
|
||||
global $DB;
|
||||
|
||||
[
|
||||
'tooltypeid' => $tooltypeid,
|
||||
'courseid' => $courseid,
|
||||
'coursevisible' => $showinactivitychooser,
|
||||
] = self::validate_parameters(self::execute_parameters(), [
|
||||
'tooltypeid' => $tooltypeid,
|
||||
'courseid' => $courseid,
|
||||
'coursevisible' => $showinactivitychooser,
|
||||
]);
|
||||
|
||||
$context = \context_course::instance($courseid);
|
||||
self::validate_context($context);
|
||||
require_capability('mod/lti:addcoursetool', $context);
|
||||
|
||||
if ($showinactivitychooser) {
|
||||
$coursevisible = LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
} else {
|
||||
$coursevisible = LTI_COURSEVISIBLE_PRECONFIGURED;
|
||||
}
|
||||
$ltitype = $DB->get_record('lti_types', ['id' => $tooltypeid]);
|
||||
$ltitype->coursevisible = $coursevisible;
|
||||
|
||||
$config = new \stdClass();
|
||||
$config->lti_coursevisible = $coursevisible;
|
||||
|
||||
if (intval($ltitype->course) !== intval(get_site()->id)) {
|
||||
// It is course tool - just update it.
|
||||
lti_update_type($ltitype, $config);
|
||||
} else {
|
||||
// This is site tool, but we would like to have course level setting for it.
|
||||
$lticoursevisible = $DB->get_record('lti_coursevisible', ['typeid' => $tooltypeid, 'courseid' => $courseid]);
|
||||
if (!$lticoursevisible) {
|
||||
$lticoursevisible = new \stdClass();
|
||||
$lticoursevisible->typeid = $tooltypeid;
|
||||
$lticoursevisible->courseid = $courseid;
|
||||
$lticoursevisible->coursevisible = $coursevisible;
|
||||
$DB->insert_record('lti_coursevisible', $lticoursevisible);
|
||||
} else {
|
||||
$lticoursevisible->coursevisible = $coursevisible;
|
||||
$DB->update_record('lti_coursevisible', $lticoursevisible);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service returns definition.
|
||||
*
|
||||
* @return external_value
|
||||
*/
|
||||
public static function execute_returns(): external_value {
|
||||
return new external_value(PARAM_BOOL, 'Success');
|
||||
}
|
||||
}
|
@ -48,25 +48,36 @@ class types_helper {
|
||||
if (empty($coursevisible)) {
|
||||
$coursevisible = [LTI_COURSEVISIBLE_PRECONFIGURED, LTI_COURSEVISIBLE_ACTIVITYCHOOSER];
|
||||
}
|
||||
list($coursevisiblesql, $coursevisparams) = $DB->get_in_or_equal($coursevisible, SQL_PARAMS_NAMED, 'coursevisible');
|
||||
[$coursevisiblesql, $coursevisparams] = $DB->get_in_or_equal($coursevisible, SQL_PARAMS_NAMED, 'coursevisible');
|
||||
[$coursevisiblesql1, $coursevisparams1] = $DB->get_in_or_equal($coursevisible, SQL_PARAMS_NAMED, 'coursevisible');
|
||||
[$coursevisibleoverriddensql, $coursevisoverriddenparams] = $DB->get_in_or_equal(
|
||||
$coursevisible,
|
||||
SQL_PARAMS_NAMED,
|
||||
'coursevisibleoverridden');
|
||||
|
||||
$coursecond = implode(" OR ", ["t.course = :courseid", "t.course = :siteid"]);
|
||||
$coursecategory = $DB->get_field('course', 'category', ['id' => $courseid]);
|
||||
$query = "SELECT t.*
|
||||
FROM {lti_types} t
|
||||
LEFT JOIN {lti_types_categories} tc ON t.id = tc.typeid
|
||||
WHERE t.coursevisible $coursevisiblesql
|
||||
AND ($coursecond)
|
||||
AND t.state = :active
|
||||
AND (tc.id IS NULL OR tc.categoryid = :categoryid)
|
||||
ORDER BY t.name ASC";
|
||||
$query = "SELECT *
|
||||
FROM (SELECT t.*, c.coursevisible as coursevisibleoverridden
|
||||
FROM {lti_types} t
|
||||
LEFT JOIN {lti_types_categories} tc ON t.id = tc.typeid
|
||||
LEFT JOIN {lti_coursevisible} c ON c.typeid = t.id AND c.courseid = $courseid
|
||||
WHERE (t.coursevisible $coursevisiblesql OR c.coursevisible $coursevisiblesql1)
|
||||
AND ($coursecond)
|
||||
AND t.state = :active
|
||||
AND (tc.id IS NULL OR tc.categoryid = :categoryid)) tt
|
||||
WHERE tt.coursevisibleoverridden IS NULL
|
||||
OR tt.coursevisibleoverridden $coursevisibleoverriddensql";
|
||||
|
||||
return $DB->get_records_sql($query,
|
||||
return $DB->get_records_sql(
|
||||
$query,
|
||||
[
|
||||
'siteid' => $SITE->id,
|
||||
'courseid' => $courseid,
|
||||
'active' => LTI_TOOL_STATE_CONFIGURED,
|
||||
'categoryid' => $coursecategory
|
||||
] + $coursevisparams);
|
||||
'categoryid' => $coursecategory,
|
||||
'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
|
||||
] + $coursevisparams + $coursevisparams1 + $coursevisoverriddenparams
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use core_reportbuilder\local\helpers\database;
|
||||
use core_reportbuilder\local\report\column;
|
||||
use mod_lti\reportbuilder\local\entities\tool_types;
|
||||
use core_reportbuilder\system_report;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Course external tools list system report class implementation.
|
||||
@ -109,6 +110,7 @@ class course_external_tools_list extends system_report {
|
||||
*/
|
||||
protected function add_columns(tool_types $tooltypesentity): void {
|
||||
$entitymainalias = $tooltypesentity->get_table_alias('lti_types');
|
||||
$courseid = $this->course->id;
|
||||
|
||||
$columns = [
|
||||
'tool_types:name',
|
||||
@ -129,6 +131,57 @@ class course_external_tools_list extends system_report {
|
||||
->add_field("{$entitymainalias}.id")
|
||||
->add_callback(fn() => $this->perrowtoolusage);
|
||||
|
||||
// Enable toggle column.
|
||||
$this->add_column((new column(
|
||||
'showinactivitychooser',
|
||||
new \lang_string('showinactivitychooser', 'mod_lti'),
|
||||
$tooltypesentity->get_entity_name()
|
||||
))
|
||||
// Site tools can be overridden on course level.
|
||||
->add_join("LEFT JOIN {lti_coursevisible} lc ON lc.typeid = {$entitymainalias}.id AND lc.courseid = $courseid")
|
||||
->set_type(column::TYPE_INTEGER)
|
||||
->add_fields("{$entitymainalias}.id, {$entitymainalias}.coursevisible, lc.coursevisible as coursevisibleoverridden")
|
||||
->set_is_sortable(false)
|
||||
->set_callback(static function(int $id, stdClass $row): string {
|
||||
global $PAGE, $COURSE;
|
||||
$coursevisible = $row->coursevisible;
|
||||
$courseid = $COURSE->id;
|
||||
if (!empty($row->coursevisibleoverridden)) {
|
||||
$coursevisible = $row->coursevisibleoverridden;
|
||||
}
|
||||
|
||||
if ($coursevisible == LTI_COURSEVISIBLE_ACTIVITYCHOOSER) {
|
||||
$coursevisible = true;
|
||||
} else {
|
||||
$coursevisible = false;
|
||||
}
|
||||
|
||||
$renderer = $PAGE->get_renderer('core_reportbuilder');
|
||||
$attributes = [
|
||||
['name' => 'id', 'value' => $row->id],
|
||||
['name' => 'courseid', 'value' => $courseid],
|
||||
['name' => 'action', 'value' => 'showinactivitychooser-toggle'],
|
||||
['name' => 'state', 'value' => $coursevisible],
|
||||
];
|
||||
$label = $coursevisible ? get_string('dontshowinactivitychooser', 'mod_lti')
|
||||
: get_string('showinactivitychooser', 'mod_lti');
|
||||
|
||||
$disabled = false;
|
||||
if (!has_capability('mod/lti:addcoursetool', \context_course::instance($courseid))) {
|
||||
$disabled = true;
|
||||
}
|
||||
|
||||
return $renderer->render_from_template('core/toggle', [
|
||||
'id' => 'showinactivitychooser-toggle-' . $row->id,
|
||||
'checked' => $coursevisible,
|
||||
'disabled' => $disabled,
|
||||
'dataattributes' => $attributes,
|
||||
'label' => $label,
|
||||
'labelclasses' => 'sr-only'
|
||||
]);
|
||||
})
|
||||
);
|
||||
|
||||
// Attempt to create a dummy actions column, working around the limitations of the official actions feature.
|
||||
$this->add_column(new column(
|
||||
'actions', new \lang_string('actions'),
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="mod/lti/db" VERSION="20230725" COMMENT="XMLDB file for Moodle mod/lti"
|
||||
<XMLDB PATH="mod/lti/db" VERSION="20230814" COMMENT="XMLDB file for Moodle mod/lti"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -175,5 +175,20 @@
|
||||
<KEY NAME="categoryid" TYPE="foreign" FIELDS="categoryid" REFTABLE="course_categories" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
<TABLE NAME="lti_coursevisible" COMMENT="Table to store coursevisible setting for site tool on course level">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="typeid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Course ID"/>
|
||||
<FIELD NAME="coursevisible" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="courseid" UNIQUE="false" FIELDS="courseid"/>
|
||||
<INDEX NAME="typeid" UNIQUE="false" FIELDS="typeid"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
|
@ -154,6 +154,14 @@ $functions = array(
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_toggle_showinactivitychooser' => array(
|
||||
'classname' => 'mod_lti\external\toggle_showinactivitychooser',
|
||||
'description' => 'Toggle showinactivitychooser for a course tool type',
|
||||
'type' => 'write',
|
||||
'capabilities' => 'mod/lti:addcoursetool',
|
||||
'ajax' => true
|
||||
),
|
||||
|
||||
'mod_lti_is_cartridge' => array(
|
||||
'classname' => 'mod_lti_external',
|
||||
'methodname' => 'is_cartridge',
|
||||
|
@ -133,10 +133,31 @@ function xmldb_lti_upgrade($oldversion) {
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Lti savepoint reached.
|
||||
upgrade_mod_savepoint(true, 2023070501, 'lti');
|
||||
}
|
||||
|
||||
if ($oldversion < 2023081101) {
|
||||
// Define communication table.
|
||||
$table = new xmldb_table('lti_coursevisible');
|
||||
|
||||
// Adding fields to table lti_coursevisible.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
|
||||
$table->add_field('typeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
|
||||
$table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'typeid');
|
||||
$table->add_field('coursevisible', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'courseid');
|
||||
|
||||
// Add key.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
|
||||
|
||||
// Conditionally launch create table for communication.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Lti savepoint reached.
|
||||
upgrade_mod_savepoint(true, 2023081101, 'lti');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -523,6 +523,8 @@ $string['share_roster_help'] = 'Specify whether the tool can access the list of
|
||||
|
||||
Note that this setting may be overridden in the tool configuration.';
|
||||
$string['show_in_course_activity_chooser'] = 'Show in activity chooser and as a preconfigured tool';
|
||||
$string['showinactivitychooser'] = 'Show in activity chooser';
|
||||
$string['dontshowinactivitychooser'] = 'Don\'t show in activity chooser';
|
||||
$string['show_in_course_lti1'] = 'Tool configuration usage';
|
||||
$string['show_in_course_lti1_help'] = 'This tool may be shown in the activity chooser for a teacher to select to add to a course. Alternatively, it may be shown in the preconfigured tool drop-down menu when adding an external tool to a course. A further option is for the tool configuration to only be used if the exact tool URL is entered when adding an external tool to a course.';
|
||||
$string['show_in_course_lti2'] = 'Tool configuration usage';
|
||||
|
@ -147,3 +147,136 @@ Feature: Manage course tools
|
||||
And the field "Tool URL" matches value "http://www.example.com/lti/provider.php"
|
||||
And the field "Icon URL" matches value "http://download.moodle.org/unittest/test.jpg"
|
||||
And the field "Secure icon URL" matches value "https://download.moodle.org/unittest/test.jpg"
|
||||
|
||||
@javascript
|
||||
Scenario: Site tool appearing in activity chooser according to settings
|
||||
Given the following "mod_lti > tool types" exist:
|
||||
| name | baseurl | coursevisible | state |
|
||||
| Teaching Tool 1 | /mod/lti/tests/fixtures/tool_provider.php | 2 | 1 |
|
||||
| Teaching Tool 2 | /mod/lti/tests/fixtures/tool_provider.php | 1 | 1 |
|
||||
| Teaching Tool 3 | /mod/lti/tests/fixtures/tool_provider.php | 0 | 1 |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 2 | C2 | 0 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C2 | editingteacher |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should see "Teaching Tool 1" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 2" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 3" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I should not see "Teaching Tool 3"
|
||||
And I click on "Don't show in activity chooser" "field" in the "Teaching Tool 1" "table_row"
|
||||
And I click on "Show in activity chooser" "field" in the "Teaching Tool 2" "table_row"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should not see "Teaching Tool 1" in the ".modal-body" "css_element"
|
||||
And I should see "Teaching Tool 2" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 3" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
|
||||
# Should not affect other courses.
|
||||
And I am on "Course 2" course homepage
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should see "Teaching Tool 1" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 2" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 3" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
|
||||
And I am on "Course 1" course homepage
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I click on "Show in activity chooser" "field" in the "Teaching Tool 1" "table_row"
|
||||
And I click on "Don't show in activity chooser" "field" in the "Teaching Tool 2" "table_row"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should see "Teaching Tool 1" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 2" in the ".modal-body" "css_element"
|
||||
And I should not see "Teaching Tool 3" in the ".modal-body" "css_element"
|
||||
|
||||
When the following "role capability" exists:
|
||||
| role | editingteacher |
|
||||
| mod/lti:addcoursetool | prohibit |
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
Then the "Don't show in activity chooser" "field" should be disabled
|
||||
And the "Show in activity chooser" "field" should be disabled
|
||||
|
||||
@javascript
|
||||
Scenario: Course tool appearing in activity chooser according to settings
|
||||
Given the following "mod_lti > course tools" exist:
|
||||
| name | baseurl | course | coursevisible |
|
||||
| Course Tool 1 | /mod/lti/tests/fixtures/tool_provider.php | C1 | 2 |
|
||||
| Course Tool 2 | /mod/lti/tests/fixtures/tool_provider.php | C1 | 1 |
|
||||
And I log in as "teacher1"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should see "Course Tool 1" in the ".modal-body" "css_element"
|
||||
And I should not see "Course Tool 2" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I click on "Don't show in activity chooser" "field" in the "Course Tool 1" "table_row"
|
||||
And I click on "Show in activity chooser" "field" in the "Course Tool 2" "table_row"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should not see "Course Tool 1" in the ".modal-body" "css_element"
|
||||
And I should see "Course Tool 2" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I click on "Show in activity chooser" "field" in the "Course Tool 1" "table_row"
|
||||
And I click on "Don't show in activity chooser" "field" in the "Course Tool 2" "table_row"
|
||||
And I am on "Course 1" course homepage
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
And I should see "Course Tool 1" in the ".modal-body" "css_element"
|
||||
And I should not see "Course Tool 2" in the ".modal-body" "css_element"
|
||||
|
||||
When the following "role capability" exists:
|
||||
| role | editingteacher |
|
||||
| mod/lti:addcoursetool | prohibit |
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
Then the "Don't show in activity chooser" "field" should be disabled
|
||||
And the "Show in activity chooser" "field" should be disabled
|
||||
|
||||
@javascript
|
||||
Scenario: Site and course tools settings are preserved when backup and restore
|
||||
Given the following "mod_lti > tool types" exist:
|
||||
| name | baseurl | coursevisible | state |
|
||||
| Teaching Tool 1 | /mod/lti/tests/fixtures/tool_provider.php | 2 | 1 |
|
||||
| Teaching Tool 2 | /mod/lti/tests/fixtures/tool_provider.php | 1 | 1 |
|
||||
And the following "mod_lti > course tools" exist:
|
||||
| name | description | baseurl | course |
|
||||
| Course Tool 1 | Example description | https://example.com/tool | C1 |
|
||||
And I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
And I add a "Teaching Tool 1" to section "1"
|
||||
And I set the field "Activity name" to "Test tool activity 1"
|
||||
And I press "Save and return to course"
|
||||
And I add a "Course Tool 1" to section "1"
|
||||
And I set the field "Activity name" to "Course tool activity 1"
|
||||
And I press "Save and return to course"
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I click on "Don't show in activity chooser" "field" in the "Teaching Tool 1" "table_row"
|
||||
And I click on "Show in activity chooser" "field" in the "Teaching Tool 2" "table_row"
|
||||
And I click on "Don't show in activity chooser" "field" in the "Course Tool 1" "table_row"
|
||||
And I am on "Course 1" course homepage
|
||||
And I add a "Teaching Tool 2" to section "1"
|
||||
And I set the field "Activity name" to "Test tool activity 2"
|
||||
And I press "Save and return to course"
|
||||
When I backup "Course 1" course using this options:
|
||||
| Confirmation | Filename | test_backup.mbz |
|
||||
And I restore "test_backup.mbz" backup into a new course using this options:
|
||||
| Schema | Course name | Restored course |
|
||||
And I should see "Restored course"
|
||||
And I click on "Add an activity or resource" "button" in the "Topic 1" "section"
|
||||
Then I should not see "Teaching Tool 1" in the ".modal-body" "css_element"
|
||||
And I should see "Teaching Tool 2" in the ".modal-body" "css_element"
|
||||
And I should not see "Course Tool 2" in the ".modal-body" "css_element"
|
||||
And I click on "Close" "button" in the ".modal-dialog" "css_element"
|
||||
And I navigate to "LTI External tools" in current page administration
|
||||
And I should see "Show in activity chooser" in the "Teaching Tool 1" "table_row"
|
||||
And I should see "Don't show in activity chooser" in the "Teaching Tool 2" "table_row"
|
||||
And I should see "Show in activity chooser" in the "Course Tool 1" "table_row"
|
||||
|
111
mod/lti/tests/external/toggle_showinactivitychooser_test.php
vendored
Normal file
111
mod/lti/tests/external/toggle_showinactivitychooser_test.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?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_lti\external;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/mod/lti/tests/mod_lti_testcase.php');
|
||||
|
||||
/**
|
||||
* PHPUnit tests for toggle_showinactivitychooser external function.
|
||||
*
|
||||
* @package mod_lti
|
||||
* @copyright 2023 Ilya Tregubov <ilya.a.tregubov@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @coversDefaultClass \mod_lti\external\toggle_showinactivitychooser
|
||||
*/
|
||||
class toggle_showinactivitychooser_test extends \mod_lti_testcase {
|
||||
|
||||
/**
|
||||
* Test toggle_showinactivitychooser for course tool.
|
||||
* @covers ::execute
|
||||
*/
|
||||
public function test_toggle_showinactivitychooser_course_tool() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$editingteacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$this->setUser($editingteacher);
|
||||
|
||||
$typeid = lti_add_type(
|
||||
(object) [
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED,
|
||||
'course' => $course->id,
|
||||
'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER
|
||||
],
|
||||
(object) [
|
||||
'lti_typename' => "My course tool",
|
||||
'lti_toolurl' => 'http://example.com',
|
||||
'lti_ltiversion' => 'LTI-1p0',
|
||||
'lti_coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER
|
||||
]
|
||||
);
|
||||
toggle_showinactivitychooser::execute($typeid, $course->id, false);
|
||||
$sql = "SELECT lt.coursevisible coursevisible1, ltc.value AS coursevisible2
|
||||
FROM {lti_types} lt
|
||||
LEFT JOIN {lti_types_config} ltc ON lt.id = ltc.typeid
|
||||
WHERE lt.id = ?
|
||||
AND ltc.name = 'coursevisible'";
|
||||
$actual = $DB->get_record_sql($sql, [$typeid]);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_PRECONFIGURED, $actual->coursevisible1);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_PRECONFIGURED, $actual->coursevisible2);
|
||||
|
||||
toggle_showinactivitychooser::execute($typeid, $course->id, true);
|
||||
$actual = $DB->get_record_sql($sql, [$typeid]);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible1);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test toggle_showinactivitychooser for site tool.
|
||||
* @covers ::execute
|
||||
*/
|
||||
public function test_toggle_showinactivitychooser_site_tool() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$editingteacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$this->setUser($editingteacher);
|
||||
|
||||
$type = $this->generate_tool_type(123); // Creates a site tool.
|
||||
|
||||
toggle_showinactivitychooser::execute($type->id, $course->id, false);
|
||||
$sql = "SELECT lt.coursevisible coursevisible1, ltc.value AS coursevisible2, lc.coursevisible AS coursevisible3
|
||||
FROM {lti_types} lt
|
||||
LEFT JOIN {lti_types_config} ltc ON lt.id = ltc.typeid
|
||||
LEFT JOIN {lti_coursevisible} lc ON lt.id = lc.typeid
|
||||
WHERE lt.id = ?
|
||||
AND lc.courseid = ?
|
||||
AND ltc.name = 'coursevisible'";
|
||||
$actual = $DB->get_record_sql($sql, [$type->id, $course->id]);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible1);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible2);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_PRECONFIGURED, $actual->coursevisible3);
|
||||
|
||||
toggle_showinactivitychooser::execute($type->id, $course->id, true);
|
||||
$actual = $DB->get_record_sql($sql, [$type->id, $course->id]);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible1);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible2);
|
||||
$this->assertEquals(LTI_COURSEVISIBLE_ACTIVITYCHOOSER, $actual->coursevisible3);
|
||||
}
|
||||
|
||||
}
|
@ -151,13 +151,14 @@ class mod_lti_generator extends testing_module_generator {
|
||||
}
|
||||
|
||||
$type['baseurl'] = (new moodle_url($type['baseurl']))->out(false); // Permits relative URLs in behat features.
|
||||
$type['coursevisible'] = LTI_COURSEVISIBLE_ACTIVITYCHOOSER; // The default for course tools.
|
||||
$type['coursevisible'] = $type['coursevisible'] ?? LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
$type['state'] = LTI_TOOL_STATE_CONFIGURED; // The default for course tools.
|
||||
|
||||
// Sensible defaults permitting the tool type to be used in a launch.
|
||||
$type['lti_acceptgrades'] = $type['lti_acceptgrades'] ?? LTI_SETTING_ALWAYS;
|
||||
$type['lti_sendname'] = $type['lti_sendname'] ?? LTI_SETTING_ALWAYS;
|
||||
$type['lti_sendemailaddr'] = $type['lti_sendemailaddr'] ?? LTI_SETTING_ALWAYS;
|
||||
$type['lti_coursevisible'] = $type['coursevisible'] ?? LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
|
||||
// Required for cartridge processing support.
|
||||
$type['lti_toolurl'] = $type['baseurl'];
|
||||
|
@ -69,12 +69,20 @@ class types_helper_test extends mod_lti_testcase {
|
||||
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
|
||||
$teacher2 = $this->getDataGenerator()->create_and_enrol($course2, 'editingteacher');
|
||||
|
||||
// Create the following tool types for testing:
|
||||
// - Site tool configured as "Do not show" (LTI_COURSEVISIBLE_NO).
|
||||
// - Site tool configured as "Show as a preconfigured tool only" (LTI_COURSEVISIBLE_PRECONFIGURED).
|
||||
// - Site tool configured as "Show as a preconfigured tool and in the activity chooser" (LTI_COURSEVISIBLE_ACTIVITYCHOOSER).
|
||||
// - Course tool which, by default, is configured as LTI_COURSEVISIBLE_ACTIVITYCHOOSER).
|
||||
// - Site tool configured to "Show as a preconfigured tool and in the activity chooser" but restricted to a category.
|
||||
/*
|
||||
Create the following tool types for testing:
|
||||
| tooltype | sitecoursevisible | coursecoursevisible | restrictedtocategory |
|
||||
| site | LTI_COURSEVISIBLE_NO | | |
|
||||
| site | LTI_COURSEVISIBLE_PRECONFIGURED | | |
|
||||
| site | LTI_COURSEVISIBLE_PRECONFIGURED | LTI_COURSEVISIBLE_PRECONFIGURED | |
|
||||
| site | LTI_COURSEVISIBLE_PRECONFIGURED | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | |
|
||||
| site | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | | |
|
||||
| site | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | |
|
||||
| site | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | LTI_COURSEVISIBLE_PRECONFIGURED | |
|
||||
| site | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | yes |
|
||||
| course | LTI_COURSEVISIBLE_ACTIVITYCHOOSER | | |
|
||||
| course | LTI_COURSEVISIBLE_PRECONFIGURED | | |
|
||||
*/
|
||||
|
||||
/** @var \mod_lti_generator $ltigenerator */
|
||||
$ltigenerator = $this->getDataGenerator()->get_plugin_generator('mod_lti');
|
||||
@ -108,41 +116,129 @@ class types_helper_test extends mod_lti_testcase {
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED,
|
||||
'lti_coursecategories' => $coursecat2->id
|
||||
]);
|
||||
$ltigenerator->create_tool_types([
|
||||
'name' => 'site tool preconfigured only, overridden to preconfigured only in course',
|
||||
'baseurl' => 'http://example.com/tool/6',
|
||||
'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED,
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED
|
||||
]);
|
||||
$tool = $DB->get_record('lti_types',
|
||||
['name' => 'site tool preconfigured only, overridden to preconfigured only in course']);
|
||||
$record = new \stdClass();
|
||||
$record->typeid = $tool->id;
|
||||
$record->courseid = $course->id;
|
||||
$record->coursevisible = LTI_COURSEVISIBLE_PRECONFIGURED;
|
||||
$DB->insert_record('lti_coursevisible', $record);
|
||||
|
||||
$ltigenerator->create_tool_types([
|
||||
'name' => 'site tool preconfigured only, overridden to activity chooser in course',
|
||||
'baseurl' => 'http://example.com/tool/7',
|
||||
'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED,
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED
|
||||
]);
|
||||
$tool = $DB->get_record('lti_types', ['name' => 'site tool preconfigured only, overridden to activity chooser in course']);
|
||||
$record = new \stdClass();
|
||||
$record->typeid = $tool->id;
|
||||
$record->courseid = $course->id;
|
||||
$record->coursevisible = LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
$DB->insert_record('lti_coursevisible', $record);
|
||||
|
||||
$ltigenerator->create_tool_types([
|
||||
'name' => 'site tool preconfigured and activity chooser, overridden to activity chooser in course',
|
||||
'baseurl' => 'http://example.com/tool/8',
|
||||
'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED
|
||||
]);
|
||||
$tool = $DB->get_record('lti_types',
|
||||
['name' => 'site tool preconfigured and activity chooser, overridden to activity chooser in course']);
|
||||
$record = new \stdClass();
|
||||
$record->typeid = $tool->id;
|
||||
$record->courseid = $course->id;
|
||||
$record->coursevisible = LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
$DB->insert_record('lti_coursevisible', $record);
|
||||
|
||||
$ltigenerator->create_tool_types([
|
||||
'name' => 'site tool preconfigured and activity chooser, overridden to preconfigured in course',
|
||||
'baseurl' => 'http://example.com/tool/9',
|
||||
'coursevisible' => LTI_COURSEVISIBLE_ACTIVITYCHOOSER,
|
||||
'state' => LTI_TOOL_STATE_CONFIGURED
|
||||
]);
|
||||
$tool = $DB->get_record('lti_types',
|
||||
['name' => 'site tool preconfigured and activity chooser, overridden to preconfigured in course']);
|
||||
$record = new \stdClass();
|
||||
$record->typeid = $tool->id;
|
||||
$record->courseid = $course->id;
|
||||
$record->coursevisible = LTI_COURSEVISIBLE_PRECONFIGURED;
|
||||
$DB->insert_record('lti_coursevisible', $record);
|
||||
|
||||
$ltigenerator->create_course_tool_types([
|
||||
'name' => 'course tool preconfigured',
|
||||
'baseurl' => 'http://example.com/tool/91',
|
||||
'course' => $course->id,
|
||||
'coursevisible' => LTI_COURSEVISIBLE_PRECONFIGURED
|
||||
]);
|
||||
|
||||
// Request using the default 'coursevisible' param will include all tools except the one configured as "Do not show" and
|
||||
// the tool restricted to category 2.
|
||||
$coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id);
|
||||
$this->assertCount(3, $coursetooltypes);
|
||||
$this->assertEmpty(array_diff(
|
||||
['http://example.com/tool/2', 'http://example.com/tool/3', 'http://example.com/tool/4'],
|
||||
array_column($coursetooltypes, 'baseurl')
|
||||
));
|
||||
$this->assertCount(8, $coursetooltypes);
|
||||
$this->assertEmpty(array_diff([
|
||||
'http://example.com/tool/2',
|
||||
'http://example.com/tool/3',
|
||||
'http://example.com/tool/4',
|
||||
'http://example.com/tool/6',
|
||||
'http://example.com/tool/7',
|
||||
'http://example.com/tool/8',
|
||||
'http://example.com/tool/9',
|
||||
'http://example.com/tool/91',
|
||||
], array_column($coursetooltypes, 'baseurl')));
|
||||
|
||||
// Request for only those tools configured to show in the activity chooser for the teacher.
|
||||
$coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id,
|
||||
[LTI_COURSEVISIBLE_ACTIVITYCHOOSER]);
|
||||
$this->assertCount(2, $coursetooltypes);
|
||||
$this->assertEmpty(array_diff(
|
||||
['http://example.com/tool/3', 'http://example.com/tool/4'],
|
||||
array_column($coursetooltypes, 'baseurl')
|
||||
));
|
||||
$this->assertCount(4, $coursetooltypes);
|
||||
$expected = [
|
||||
'http://example.com/tool/3',
|
||||
'http://example.com/tool/4',
|
||||
'http://example.com/tool/7',
|
||||
'http://example.com/tool/8'
|
||||
];
|
||||
sort($expected);
|
||||
$actual = array_column($coursetooltypes, 'baseurl');
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Request for only those tools configured to show as a preconfigured tool for the teacher.
|
||||
$coursetooltypes = types_helper::get_lti_types_by_course($course->id, $teacher->id,
|
||||
[LTI_COURSEVISIBLE_PRECONFIGURED]);
|
||||
$this->assertCount(1, $coursetooltypes);
|
||||
$this->assertEmpty(array_diff(
|
||||
['http://example.com/tool/2'],
|
||||
array_column($coursetooltypes, 'baseurl')
|
||||
));
|
||||
$this->assertCount(4, $coursetooltypes);
|
||||
$expected = [
|
||||
'http://example.com/tool/2',
|
||||
'http://example.com/tool/6',
|
||||
'http://example.com/tool/9',
|
||||
'http://example.com/tool/91'
|
||||
];
|
||||
sort($expected);
|
||||
$actual = array_column($coursetooltypes, 'baseurl');
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Request for teacher2 in course2 (course category 2).
|
||||
$coursetooltypes = types_helper::get_lti_types_by_course($course2->id, $teacher2->id);
|
||||
$this->assertCount(3, $coursetooltypes);
|
||||
$this->assertEmpty(array_diff(
|
||||
['http://example.com/tool/2', 'http://example.com/tool/3', 'http://example.com/tool/5'],
|
||||
array_column($coursetooltypes, 'baseurl')
|
||||
));
|
||||
$this->assertCount(7, $coursetooltypes);
|
||||
$expected = [
|
||||
'http://example.com/tool/2',
|
||||
'http://example.com/tool/3',
|
||||
'http://example.com/tool/5',
|
||||
'http://example.com/tool/6',
|
||||
'http://example.com/tool/7',
|
||||
'http://example.com/tool/8',
|
||||
'http://example.com/tool/9'
|
||||
];
|
||||
sort($expected);
|
||||
$actual = array_column($coursetooltypes, 'baseurl');
|
||||
sort($actual);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
// Request for a teacher who cannot use preconfigured tools in the course.
|
||||
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
|
||||
|
@ -48,8 +48,11 @@ abstract class mod_lti_testcase extends externallib_advanced_testcase {
|
||||
$type->description = "Example description $uniqueid";
|
||||
$type->toolproxyid = $toolproxyid;
|
||||
$type->baseurl = $this->getExternalTestFileUrl("/test$uniqueid.html");
|
||||
$type->coursevisible = LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
$config = new stdClass();
|
||||
$config->lti_coursevisible = LTI_COURSEVISIBLE_ACTIVITYCHOOSER;
|
||||
|
||||
$type->id = lti_add_type($type, new stdClass());
|
||||
$type->id = lti_add_type($type, $config);
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2023081100; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2023081101; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2023041800; // Requires this Moodle version.
|
||||
$plugin->component = 'mod_lti'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->cron = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user