mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 17:06:53 +02:00
MDL-52534 tool_lp: Competencies can be attached to activities
This commit is contained in:
parent
8995c2702f
commit
db65073748
21 changed files with 1361 additions and 9 deletions
|
@ -64,6 +64,35 @@ class backup_tool_lp_plugin extends backup_tool_plugin {
|
|||
return $plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the module plugin structure.
|
||||
*
|
||||
* @return backup_plugin_element
|
||||
*/
|
||||
protected function define_module_plugin_structure() {
|
||||
$plugin = $this->get_plugin_element(null, $this->get_include_condition(), 'include');
|
||||
|
||||
$pluginwrapper = new backup_nested_element($this->get_recommended_name());
|
||||
$plugin->add_child($pluginwrapper);
|
||||
|
||||
$coursecompetencies = new backup_nested_element('course_module_competencies');
|
||||
$pluginwrapper->add_child($coursecompetencies);
|
||||
|
||||
$competency = new backup_nested_element('competency', null, array('idnumber', 'ruleoutcome',
|
||||
'sortorder', 'frameworkidnumber'));
|
||||
$coursecompetencies->add_child($competency);
|
||||
|
||||
$sql = 'SELECT c.idnumber, cmc.ruleoutcome, cmc.sortorder, f.idnumber AS frameworkidnumber
|
||||
FROM {' . \tool_lp\course_module_competency::TABLE . '} cmc
|
||||
JOIN {' . \tool_lp\competency::TABLE . '} c ON c.id = cmc.competencyid
|
||||
JOIN {' . \tool_lp\competency_framework::TABLE . '} f ON f.id = c.competencyframeworkid
|
||||
WHERE cmc.cmid = :coursemoduleid
|
||||
ORDER BY cmc.sortorder';
|
||||
$competency->set_source_sql($sql, array('coursemoduleid' => backup::VAR_MODID));
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a condition for whether we include this report in the backup or not.
|
||||
*
|
||||
|
|
|
@ -47,12 +47,24 @@ class restore_tool_lp_plugin extends restore_tool_plugin {
|
|||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the paths.
|
||||
*
|
||||
* @return restore_path_element[]
|
||||
*/
|
||||
protected function define_module_plugin_structure() {
|
||||
$paths = array(
|
||||
new restore_path_element('course_module_competency', $this->get_pathfor('/course_module_competencies/competency'))
|
||||
);
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a course competency.
|
||||
*
|
||||
* @param array $data The data.
|
||||
*/
|
||||
public function process_course_competency($data) {
|
||||
public function process_course_module_competency($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object) $data;
|
||||
|
@ -70,16 +82,16 @@ class restore_tool_lp_plugin extends restore_tool_plugin {
|
|||
|
||||
$params = array(
|
||||
'competencyid' => $competency->get_id(),
|
||||
'courseid' => $this->task->get_courseid()
|
||||
'cmid' => $this->task->get_moduleid()
|
||||
);
|
||||
$existing = \tool_lp\course_competency::record_exists_select('competencyid = :competencyid AND courseid = :courseid', $params);
|
||||
$existing = \tool_lp\course_module_competency::record_exists_select('competencyid = :competencyid AND cmid = :cmid', $params);
|
||||
|
||||
if (!$existing) {
|
||||
// Sortorder is ignored by precaution, anyway we should walk through the records in the right order.
|
||||
$record = (object) $params;
|
||||
$record->ruleoutcome = $data->ruleoutcome;
|
||||
$coursecompetency = new \tool_lp\course_competency(0, $record);
|
||||
$coursecompetency->create();
|
||||
$coursemodulecompetency = new \tool_lp\course_module_competency(0, $record);
|
||||
$coursemodulecompetency->create();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ use context;
|
|||
use context_helper;
|
||||
use context_system;
|
||||
use context_course;
|
||||
use context_module;
|
||||
use context_user;
|
||||
use coding_exception;
|
||||
use require_login_exception;
|
||||
|
@ -806,6 +807,66 @@ class api {
|
|||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the courses modules using a competency in a course.
|
||||
*
|
||||
* @param int $competencyid The id of the competency to check.
|
||||
* @param int $courseid The id of the course to check.
|
||||
* @return array[stdClass] Array of stdClass containing course module records.
|
||||
*/
|
||||
public static function list_course_modules_using_competency($competencyid, $courseid) {
|
||||
|
||||
$result = array();
|
||||
self::validate_course($courseid);
|
||||
|
||||
$coursecontext = context_course::instance($courseid);
|
||||
|
||||
// We will not check each module - course permissions should be enough.
|
||||
$capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
|
||||
if (!has_any_capability($capabilities, $coursecontext)) {
|
||||
throw new required_capability_exception($coursecontext, 'tool/lp:coursecompetencyread', 'nopermissions', '');
|
||||
}
|
||||
|
||||
$cmlist = course_module_competency::list_course_modules($competencyid, $courseid);
|
||||
foreach ($cmlist as $id => $cm) {
|
||||
array_push($result, $cm);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the competencies linked to a course module.
|
||||
*
|
||||
* @param mixed $cmorid The course module, or its ID.
|
||||
* @return array[competency] Array of competency records.
|
||||
*/
|
||||
public static function list_course_module_competencies_in_course_module($cmorid) {
|
||||
$cm = $cmorid;
|
||||
if (!is_object($cmorid)) {
|
||||
$cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check the user have access to the course.
|
||||
self::validate_course($cm->course);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
|
||||
if (!has_any_capability($capabilities, $context)) {
|
||||
throw new required_capability_exception($context, 'tool/lp:coursecompetencyread', 'nopermissions', '');
|
||||
}
|
||||
|
||||
$result = array();
|
||||
self::validate_course($cm->course);
|
||||
|
||||
$cmclist = course_module_competency::list_course_module_competencies($cm->id);
|
||||
foreach ($cmclist as $id => $cmc) {
|
||||
array_push($result, $cmc);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the courses using a competency.
|
||||
*
|
||||
|
@ -978,6 +1039,47 @@ class api {
|
|||
return $uc;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the competencies associated to a course module.
|
||||
*
|
||||
* @param mixed $cmorid The course module, or its ID.
|
||||
* @return array( array(
|
||||
* 'competency' => \tool_lp\competency,
|
||||
* 'coursemodulecompetency' => \tool_lp\course_module_competency
|
||||
* ))
|
||||
*/
|
||||
public static function list_course_module_competencies($cmorid) {
|
||||
$cm = $cmorid;
|
||||
if (!is_object($cmorid)) {
|
||||
$cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check the user have access to the course.
|
||||
self::validate_course($cm->course);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$capabilities = array('tool/lp:coursecompetencyread', 'tool/lp:coursecompetencymanage');
|
||||
if (!has_any_capability($capabilities, $context)) {
|
||||
throw new required_capability_exception($context, 'tool/lp:coursecompetencyread', 'nopermissions', '');
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
// TODO We could improve the performance of this into one single query.
|
||||
$coursemodulecompetencies = course_competency::list_course_module_competencies($cm->id);
|
||||
$competencies = course_module_competency::list_competencies($cm->id);
|
||||
|
||||
// Build the return values.
|
||||
foreach ($coursemodulecompetencies as $key => $coursemodulecompetency) {
|
||||
$result[] = array(
|
||||
'competency' => $competencies[$coursemodulecompetency->get_competencyid()],
|
||||
'coursemodulecompetency' => $coursemodulecompetency
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user competency in a course.
|
||||
*
|
||||
|
@ -1146,6 +1248,171 @@ class api {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a competency to this course module.
|
||||
*
|
||||
* @param mixed $cmorid The course module, or id of the course module
|
||||
* @param int $competencyid The id of the competency
|
||||
* @return bool
|
||||
*/
|
||||
public static function add_competency_to_course_module($cmorid, $competencyid) {
|
||||
$cm = $cmorid;
|
||||
if (!is_object($cmorid)) {
|
||||
$cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check the user have access to the course.
|
||||
self::validate_course($cm->course);
|
||||
|
||||
// First we do a permissions check.
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
require_capability('tool/lp:coursecompetencymanage', $context);
|
||||
|
||||
// Check that the competency belongs to the course.
|
||||
$exists = course_competency::get_records(array('courseid' => $cm->course, 'competencyid' => $competencyid));
|
||||
if (!$exists) {
|
||||
throw new coding_exception('Cannot add a competency to a module if it does not belong to the course');
|
||||
}
|
||||
|
||||
$competency = new competency($competencyid);
|
||||
|
||||
// Can not add a competency that belong to a hidden framework.
|
||||
if ($competency->get_framework()->get_visible() == false) {
|
||||
throw new coding_exception('A competency belonging to hidden framework can not be linked to course module');
|
||||
}
|
||||
|
||||
$record = new stdClass();
|
||||
$record->cmid = $cm->id;
|
||||
$record->competencyid = $competencyid;
|
||||
|
||||
$coursemodulecompetency = new course_module_competency();
|
||||
$exists = $coursemodulecompetency->get_records(array('cmid' => $cm->id, 'competencyid' => $competencyid));
|
||||
if (!$exists) {
|
||||
$coursemodulecompetency->from_record($record);
|
||||
if ($coursemodulecompetency->create()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a competency from this course module.
|
||||
*
|
||||
* @param mixed $cmorid The course module, or id of the course module
|
||||
* @param int $competencyid The id of the competency
|
||||
* @return bool
|
||||
*/
|
||||
public static function remove_competency_from_course_module($cmorid, $competencyid) {
|
||||
$cm = $cmorid;
|
||||
if (!is_object($cmorid)) {
|
||||
$cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
|
||||
}
|
||||
// Check the user have access to the course.
|
||||
self::validate_course($cm->course);
|
||||
|
||||
// First we do a permissions check.
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
require_capability('tool/lp:coursecompetencymanage', $context);
|
||||
|
||||
$record = new stdClass();
|
||||
$record->cmid = $cm->id;
|
||||
$record->competencyid = $competencyid;
|
||||
|
||||
$competency = new competency($competencyid);
|
||||
$exists = course_module_competency::get_records(array('cmid' => $cm->id, 'competencyid' => $competencyid));
|
||||
if ($exists) {
|
||||
$coursemodulecompetency = array_pop($exists);
|
||||
return $coursemodulecompetency->delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the course module competency up or down in the display list.
|
||||
*
|
||||
* Requires tool/lp:coursecompetencymanage capability at the course module context.
|
||||
*
|
||||
* @param mixed $cmorid The course module, or id of the course module
|
||||
* @param int $competencyidfrom The id of the competency we are moving.
|
||||
* @param int $competencyidto The id of the competency we are moving to.
|
||||
* @return boolean
|
||||
*/
|
||||
public static function reorder_course_module_competency($cmorid, $competencyidfrom, $competencyidto) {
|
||||
$cm = $cmorid;
|
||||
if (!is_object($cmorid)) {
|
||||
$cm = get_coursemodule_from_id('', $cmorid, 0, true, MUST_EXIST);
|
||||
}
|
||||
// Check the user have access to the course.
|
||||
self::validate_course($cm->course);
|
||||
|
||||
// First we do a permissions check.
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
require_capability('tool/lp:coursecompetencymanage', $context);
|
||||
|
||||
$down = true;
|
||||
$matches = course_module_competency::get_records(array('cmid' => $cm->id, 'competencyid' => $competencyidfrom));
|
||||
if (count($matches) == 0) {
|
||||
throw new coding_exception('The link does not exist');
|
||||
}
|
||||
|
||||
$competencyfrom = array_pop($matches);
|
||||
$matches = course_module_competency::get_records(array('cmid' => $cm->id, 'competencyid' => $competencyidto));
|
||||
if (count($matches) == 0) {
|
||||
throw new coding_exception('The link does not exist');
|
||||
}
|
||||
|
||||
$competencyto = array_pop($matches);
|
||||
|
||||
$all = course_module_competency::get_records(array('cmid' => $cm->id), 'sortorder', 'ASC', 0, 0);
|
||||
|
||||
if ($competencyfrom->get_sortorder() > $competencyto->get_sortorder()) {
|
||||
// We are moving up, so put it before the "to" item.
|
||||
$down = false;
|
||||
}
|
||||
|
||||
foreach ($all as $id => $coursemodulecompetency) {
|
||||
$sort = $coursemodulecompetency->get_sortorder();
|
||||
if ($down && $sort > $competencyfrom->get_sortorder() && $sort <= $competencyto->get_sortorder()) {
|
||||
$coursemodulecompetency->set_sortorder($coursemodulecompetency->get_sortorder() - 1);
|
||||
$coursemodulecompetency->update();
|
||||
} else if (!$down && $sort >= $competencyto->get_sortorder() && $sort < $competencyfrom->get_sortorder()) {
|
||||
$coursemodulecompetency->set_sortorder($coursemodulecompetency->get_sortorder() + 1);
|
||||
$coursemodulecompetency->update();
|
||||
}
|
||||
}
|
||||
$competencyfrom->set_sortorder($competencyto->get_sortorder());
|
||||
return $competencyfrom->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update ruleoutcome value for a course module competency.
|
||||
*
|
||||
* @param int|course_module_competency $coursemodulecompetencyorid The course_module_competency, or its ID.
|
||||
* @param int $ruleoutcome The value of ruleoutcome.
|
||||
* @return bool True on success.
|
||||
*/
|
||||
public static function set_course_module_competency_ruleoutcome($coursemodulecompetencyorid, $ruleoutcome) {
|
||||
$coursemodulecompetency = $coursemodulecompetencyorid;
|
||||
if (!is_object($coursemodulecompetency)) {
|
||||
$coursemodulecompetency = new course_module_competency($coursemodulecompetencyorid);
|
||||
}
|
||||
|
||||
$cm = get_coursemodule_from_id('', $coursemodulecompetency->get_cmid(), 0, true, MUST_EXIST);
|
||||
|
||||
$courseid = $cm->course;
|
||||
self::validate_course($courseid);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
require_capability('tool/lp:coursecompetencymanage', $context);
|
||||
|
||||
$coursemodulecompetency->set_ruleoutcome($ruleoutcome);
|
||||
return $coursemodulecompetency->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a competency to this course.
|
||||
*
|
||||
|
@ -3655,6 +3922,64 @@ class api {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe when a course module is marked as completed.
|
||||
*
|
||||
* Note that the user being logged in while this happens may be anyone.
|
||||
* Do not rely on capability checks here!
|
||||
*
|
||||
* @param \core\event\course_module_completion_updated $event
|
||||
* @return void
|
||||
*/
|
||||
public static function observe_course_module_completion_updated(\core\event\course_module_completion_updated $event) {
|
||||
|
||||
$eventdata = $event->get_record_snapshot('course_modules_completion', $event->objectid);
|
||||
|
||||
if ($eventdata->completionstate == COMPLETION_COMPLETE
|
||||
|| $eventdata->completionstate == COMPLETION_COMPLETE_PASS) {
|
||||
$coursemodulecompetencies = course_module_competency::list_course_module_competencies($eventdata->coursemoduleid);
|
||||
|
||||
$cm = get_coursemodule_from_id(null, $eventdata->coursemoduleid);
|
||||
$fastmodinfo = get_fast_modinfo($cm->course)->cms[$cm->id];
|
||||
|
||||
$cmname = $fastmodinfo->name;
|
||||
$url = $fastmodinfo->url;
|
||||
|
||||
foreach ($coursemodulecompetencies as $coursemodulecompetency) {
|
||||
$outcome = $coursemodulecompetency->get_ruleoutcome();
|
||||
$action = null;
|
||||
$recommend = false;
|
||||
$strdesc = 'evidence_coursemodulecompleted';
|
||||
|
||||
if ($outcome == course_module_competency::OUTCOME_EVIDENCE) {
|
||||
$action = evidence::ACTION_LOG;
|
||||
|
||||
} else if ($outcome == course_module_competency::OUTCOME_RECOMMEND) {
|
||||
$action = evidence::ACTION_LOG;
|
||||
$recommend = true;
|
||||
|
||||
} else if ($outcome == course_module_competency::OUTCOME_COMPLETE) {
|
||||
$action = evidence::ACTION_COMPLETE;
|
||||
|
||||
} else {
|
||||
throw new moodle_exception('Unexpected rule outcome: ' + $outcome);
|
||||
}
|
||||
|
||||
static::add_evidence(
|
||||
$event->relateduserid,
|
||||
$coursemodulecompetency->get_competencyid(),
|
||||
$event->contextid,
|
||||
$action,
|
||||
$strdesc,
|
||||
'tool_lp',
|
||||
$cmname,
|
||||
$recommend,
|
||||
$url
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe when a course is marked as completed.
|
||||
*
|
||||
|
|
87
admin/tool/lp/classes/course_competencies_form_element.php
Normal file
87
admin/tool/lp/classes/course_competencies_form_element.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Course competencies element.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
use tool_lp\api;
|
||||
use tool_lp\external\competency_exporter;
|
||||
require_once($CFG->libdir . '/form/autocomplete.php');
|
||||
|
||||
/**
|
||||
* Course competencies element.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_lp_course_competencies_form_element extends MoodleQuickForm_autocomplete {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @TODO: Convert this to a real constructor when the PHP7 changes are merged.
|
||||
*
|
||||
* @param string $elementName Element name
|
||||
* @param mixed $elementLabel Label(s) for an element
|
||||
* @param array $options Options to control the element's display
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array.
|
||||
*/
|
||||
function tool_lp_course_competencies_form_element($elementName=null, $elementLabel=null, $options=array(), $attributes=null) {
|
||||
global $OUTPUT;
|
||||
|
||||
if ($elementName == null) {
|
||||
// This is broken quickforms messing with the constructors.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($options['courseid'])) {
|
||||
throw new coding_exception('Course id is required for the course_competencies form element');
|
||||
}
|
||||
$courseid = $options['courseid'];
|
||||
|
||||
if (!empty($options['cmid'])) {
|
||||
$current = \tool_lp\api::list_course_module_competencies_in_course_module($options['cmid']);
|
||||
$getid = function($coursemodulecompetency) { return $coursemodulecompetency->get_competencyid(); };
|
||||
$ids = array_map($getid, $current);
|
||||
$this->setValue($ids);
|
||||
}
|
||||
|
||||
$competencies = api::list_course_competencies($courseid);
|
||||
$validoptions = array();
|
||||
|
||||
$context = context_course::instance($courseid);
|
||||
foreach ($competencies as $competency) {
|
||||
$exporter = new competency_exporter($competency['competency'], array('context' => $context));
|
||||
$templatecontext = array('competency' => $exporter->export($OUTPUT));
|
||||
$id = $competency['competency']->get_id();
|
||||
$validoptions[$id] = $OUTPUT->render_from_template('tool_lp/competency_summary', $templatecontext);
|
||||
}
|
||||
$attributes['tags'] = false;
|
||||
$attributes['multiple'] = 'multiple';
|
||||
parent::__construct($elementName, $elementLabel, $validoptions, $attributes);
|
||||
}
|
||||
}
|
|
@ -339,6 +339,16 @@ class course_competency extends persistent {
|
|||
$table = '{' . self::TABLE . '}';
|
||||
$sql = "UPDATE $table SET sortorder = sortorder -1 WHERE courseid = ? AND sortorder > ?";
|
||||
$DB->execute($sql, array($this->get_courseid(), $this->get_sortorder()));
|
||||
|
||||
// Delete all course_module_competencies for this competency in this course.
|
||||
$cmids = course_module_competency::list_course_modules($this->get_competencyid(), $this->get_courseid());
|
||||
if (!empty($cmids)) {
|
||||
list($in, $params) = $DB->get_in_or_equal(array_keys($cmids), SQL_PARAMS_NAMED);
|
||||
$params['compid'] = $this->get_competencyid();
|
||||
$DB->delete_records_select(course_module_competencies::TABLE,
|
||||
'cmid ' . $in . ' AND competencyid = :compid',
|
||||
$params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<?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/>.
|
||||
|
||||
|
||||
/**
|
||||
* Course competency rule element.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
use tool_lp\api;
|
||||
use tool_lp\external\competency_exporter;
|
||||
use tool_lp\course_module_competency;
|
||||
|
||||
require_once($CFG->libdir . '/form/select.php');
|
||||
|
||||
/**
|
||||
* Course competency rule element.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_lp_course_competency_rule_form_element extends MoodleQuickForm_select {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @TODO: Convert this to a real constructor when the PHP7 changes are merged.
|
||||
*
|
||||
* @param string $elementName Element name
|
||||
* @param mixed $elementLabel Label(s) for an element
|
||||
* @param array $options Options to control the element's display
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array.
|
||||
*/
|
||||
function tool_lp_course_competency_rule_form_element($elementName=null, $elementLabel=null, $options=array(), $attributes=null) {
|
||||
global $OUTPUT;
|
||||
|
||||
if ($elementName == null) {
|
||||
// This is broken quickforms messing with the constructors.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($options['cmid'])) {
|
||||
$cmid = $options['cmid'];
|
||||
|
||||
$current = \tool_lp\api::list_course_module_competencies_in_course_module($cmid);
|
||||
if (!empty($current)) {
|
||||
$one = array_pop($current);
|
||||
$this->setValue($one->get_ruleoutcome());
|
||||
}
|
||||
}
|
||||
$validoptions = course_module_competency::get_ruleoutcome_list();
|
||||
parent::__construct($elementName, $elementLabel, $validoptions, $attributes);
|
||||
}
|
||||
}
|
320
admin/tool/lp/classes/course_module_competency.php
Normal file
320
admin/tool/lp/classes/course_module_competency.php
Normal file
|
@ -0,0 +1,320 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class for loading/storing competencies from the DB.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_lp;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use stdClass;
|
||||
use lang_string;
|
||||
|
||||
/**
|
||||
* Class for loading/storing course_module_competencies from the DB.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_module_competency extends persistent {
|
||||
|
||||
const TABLE = 'tool_lp_module_competency';
|
||||
|
||||
/** Course competency ruleoutcome constant. */
|
||||
const OUTCOME_NONE = 0;
|
||||
/** Course competency ruleoutcome constant. */
|
||||
const OUTCOME_EVIDENCE = 1;
|
||||
/** Course competency ruleoutcome constant. */
|
||||
const OUTCOME_RECOMMEND = 2;
|
||||
/** Course competency ruleoutcome constant. */
|
||||
const OUTCOME_COMPLETE = 3;
|
||||
|
||||
/**
|
||||
* Return the definition of the properties of this model.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_properties() {
|
||||
return array(
|
||||
'cmid' => array(
|
||||
'type' => PARAM_INT
|
||||
),
|
||||
'competencyid' => array(
|
||||
'type' => PARAM_INT
|
||||
),
|
||||
'sortorder' => array(
|
||||
'type' => PARAM_INT
|
||||
),
|
||||
'ruleoutcome' => array(
|
||||
'choices' => array(self::OUTCOME_NONE,
|
||||
self::OUTCOME_EVIDENCE,
|
||||
self::OUTCOME_RECOMMEND,
|
||||
self::OUTCOME_COMPLETE
|
||||
),
|
||||
'default' => self::OUTCOME_EVIDENCE,
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to execute before validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function before_validate() {
|
||||
if (($this->get_id() && $this->get_sortorder() === null) || !$this->get_id()) {
|
||||
$this->set('sortorder', $this->count_records(array('cmid' => $this->get_cmid())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of rules.
|
||||
*
|
||||
* @return array Indexed by outcome value.
|
||||
*/
|
||||
public static function get_ruleoutcome_list() {
|
||||
static $list = null;
|
||||
|
||||
if ($list === null) {
|
||||
$list = array(
|
||||
self::OUTCOME_NONE => self::get_ruleoutcome_name(self::OUTCOME_NONE),
|
||||
self::OUTCOME_EVIDENCE => self::get_ruleoutcome_name(self::OUTCOME_EVIDENCE),
|
||||
self::OUTCOME_RECOMMEND => self::get_ruleoutcome_name(self::OUTCOME_RECOMMEND),
|
||||
self::OUTCOME_COMPLETE => self::get_ruleoutcome_name(self::OUTCOME_COMPLETE));
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable rule name.
|
||||
*
|
||||
* @param int $ruleoutcome The value of ruleoutcome.
|
||||
* @return lang_string
|
||||
*/
|
||||
public static function get_ruleoutcome_name($ruleoutcome) {
|
||||
|
||||
switch ($ruleoutcome) {
|
||||
case self::OUTCOME_NONE:
|
||||
$strname = 'none';
|
||||
break;
|
||||
case self::OUTCOME_EVIDENCE:
|
||||
$strname = 'evidence';
|
||||
break;
|
||||
case self::OUTCOME_RECOMMEND:
|
||||
$strname = 'recommend';
|
||||
break;
|
||||
case self::OUTCOME_COMPLETE:
|
||||
$strname = 'complete';
|
||||
break;
|
||||
default:
|
||||
throw new \moodle_exception('errorcompetencyrule', 'tool_lp', '', $rule);
|
||||
break;
|
||||
}
|
||||
|
||||
return new lang_string('coursemodulecompetencyoutcome_' . $strname, 'tool_lp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate cmid ID.
|
||||
*
|
||||
* @return true|lang_string
|
||||
*/
|
||||
protected function validate_cmid($data) {
|
||||
global $DB;
|
||||
if (!$DB->record_exists('course_modules', array('id' => $data))) {
|
||||
return new lang_string('invalidmodule', 'error');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate competency ID.
|
||||
*
|
||||
* @return true|lang_string
|
||||
*/
|
||||
protected function validate_competencyid($data) {
|
||||
if (!competency::record_exists($data)) {
|
||||
return new lang_string('invaliddata', 'error');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the module IDs and visible flags that include this competency in a single course.
|
||||
*
|
||||
* @param int $competencyid The competency id
|
||||
* @return array containing cmid and visible.
|
||||
*/
|
||||
public static function list_course_modules($competencyid, $courseid) {
|
||||
global $DB;
|
||||
|
||||
$results = $DB->get_records_sql('SELECT coursemodules.id as id, coursemodules.visible as visible
|
||||
FROM {' . self::TABLE . '} modcomp
|
||||
JOIN {course_modules} coursemodules
|
||||
ON modcomp.cmid = coursemodules.id
|
||||
WHERE modcomp.competencyid = ? AND coursemodules.course = ?', array($competencyid, $courseid));
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the competencies in this course module.
|
||||
*
|
||||
* @param int $cmid The course module id.
|
||||
* @return int
|
||||
*/
|
||||
public static function count_competencies($cmid) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT COUNT(comp.id)
|
||||
FROM {' . self::TABLE . '} coursemodulecomp
|
||||
JOIN {' . competency::TABLE . '} comp
|
||||
ON coursecomp.competencyid = comp.id
|
||||
WHERE coursecomp.cmid = ? ';
|
||||
$params = array($cmid);
|
||||
|
||||
$results = $DB->count_records_sql($sql, $params);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the competencies in this course module.
|
||||
*
|
||||
* @param int $cmid The course module id
|
||||
* @return competency[] Indexed by competency ID.
|
||||
*/
|
||||
public static function list_competencies($cmid) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT comp.*
|
||||
FROM {' . competency::TABLE . '} comp
|
||||
JOIN {' . self::TABLE . '} coursemodulecomp
|
||||
ON coursemodulecomp.competencyid = comp.id
|
||||
WHERE coursemodulecomp.cmid = ?';
|
||||
$params = array($cmid);
|
||||
|
||||
$sql .= ' ORDER BY coursemodulecomp.sortorder ASC';
|
||||
$results = $DB->get_recordset_sql($sql, $params);
|
||||
$instances = array();
|
||||
foreach ($results as $result) {
|
||||
$comp = new competency(0, $result);
|
||||
$instances[$comp->get_id()] = $comp;
|
||||
}
|
||||
$results->close();
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single competency from the course module (only if it is really in the course module).
|
||||
*
|
||||
* @param int $cmid The course module id
|
||||
* @param int $competencyid The competency id
|
||||
* @return competency
|
||||
*/
|
||||
public static function get_competency($cmid, $competencyid) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT comp.*
|
||||
FROM {' . competency::TABLE . '} comp
|
||||
JOIN {' . self::TABLE . '} crsmodcomp
|
||||
ON crsmodcomp.competencyid = comp.id
|
||||
WHERE crsmodcomp.cmid = ? AND crsmodcomp.competencyid = ?';
|
||||
$params = array($cmid, $competencyid);
|
||||
|
||||
$result = $DB->get_record_sql($sql, $params);
|
||||
if (!$result) {
|
||||
throw new coding_exception('The competency does not belong to this course module: ' . $competencyid . ', ' . $cmid);
|
||||
}
|
||||
|
||||
return new competency(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to execute after delete.
|
||||
*
|
||||
* @param bool $result Whether or not the delete was successful.
|
||||
* @return void
|
||||
*/
|
||||
protected function after_delete($result) {
|
||||
global $DB;
|
||||
if (!$result) {
|
||||
return;
|
||||
}
|
||||
|
||||
$table = '{' . self::TABLE . '}';
|
||||
$sql = "UPDATE $table SET sortorder = sortorder -1 WHERE cmid = ? AND sortorder > ?";
|
||||
$DB->execute($sql, array($this->get_cmid(), $this->get_sortorder()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specified mod_competency in this course.
|
||||
*
|
||||
* @param int $cmid The course module id
|
||||
* @param int $competencyid The competency id
|
||||
* @return course_module_competency
|
||||
*/
|
||||
public static function get_course_module_competency($cmid, $competencyid) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT crsmodcomp.*
|
||||
FROM {' . self::TABLE . '} crsmodcomp
|
||||
WHERE crsmodcomp.cmid = ? AND crsmodcomp.competencyid = ?';
|
||||
$params = array($cmid, $competencyid);
|
||||
|
||||
$result = $DB->get_record_sql($sql, $params);
|
||||
if (!$result) {
|
||||
throw new coding_exception('The competency does not belong to this course module: ' . $competencyid . ', ' . $cmid);
|
||||
}
|
||||
|
||||
return new course_module_competency(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the course_module_competencies in this course module.
|
||||
*
|
||||
* @param int $cmid The course module id
|
||||
* @return course_module_competency[]
|
||||
*/
|
||||
public static function list_course_module_competencies($cmid) {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT coursemodcomp.*
|
||||
FROM {' . self::TABLE . '} coursemodcomp
|
||||
JOIN {' . competency::TABLE . '} comp
|
||||
ON coursemodcomp.competencyid = comp.id
|
||||
WHERE coursemodcomp.cmid = ?';
|
||||
$params = array($cmid);
|
||||
|
||||
$sql .= ' ORDER BY coursemodcomp.sortorder ASC';
|
||||
$results = $DB->get_recordset_sql($sql, $params);
|
||||
$instances = array();
|
||||
foreach ($results as $result) {
|
||||
array_push($instances, new course_module_competency(0, $result));
|
||||
}
|
||||
$results->close();
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
}
|
|
@ -56,6 +56,7 @@ use tool_lp\external\user_evidence_competency_exporter;
|
|||
use tool_lp\external\competency_exporter;
|
||||
use tool_lp\external\course_competency_exporter;
|
||||
use tool_lp\external\course_summary_exporter;
|
||||
use tool_lp\external\course_module_summary_exporter;
|
||||
use tool_lp\external\plan_exporter;
|
||||
use tool_lp\external\template_exporter;
|
||||
use tool_lp\external\evidence_exporter;
|
||||
|
@ -1510,6 +1511,141 @@ class external extends external_api {
|
|||
return new external_value(PARAM_INT, 'The number of competencies in this course.');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns description of list_course_module_competencies() parameters.
|
||||
*
|
||||
* @return \external_function_parameters
|
||||
*/
|
||||
public static function list_course_module_competencies_parameters() {
|
||||
$cmid = new external_value(
|
||||
PARAM_INT,
|
||||
'The course module id',
|
||||
VALUE_REQUIRED
|
||||
);
|
||||
$params = array(
|
||||
'cmid' => $cmid
|
||||
);
|
||||
return new external_function_parameters($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the course modules using this competency (visible to this user) in this course.
|
||||
*
|
||||
* @param int $cmid The course module id to check.
|
||||
* @return array
|
||||
*/
|
||||
public static function list_course_module_competencies($cmid) {
|
||||
global $PAGE;
|
||||
|
||||
$params = self::validate_parameters(self::list_course_module_competencies_parameters(),
|
||||
array(
|
||||
'cmid' => $cmid
|
||||
));
|
||||
|
||||
$cm = course_module_instance_from_id($params['cmid']);
|
||||
$context = context_module::instance($cm->id);
|
||||
self::validate_context($context);
|
||||
|
||||
$output = $PAGE->get_renderer('tool_lp');
|
||||
|
||||
$apiresult = api::list_course_module_competencies($params['cmid']);
|
||||
$result = array();
|
||||
|
||||
foreach ($apiresult as $cmrecord) {
|
||||
$one = new stdClass();
|
||||
$exporter = new competency_exporter($cmrecord['competency']);
|
||||
$one->competency = $exporter->export($output);
|
||||
$exporter = new course_module_competency_exporter($cmrecord['coursemodulecompetency']);
|
||||
$one->coursemodulecompetency = $exporter->export($output);
|
||||
|
||||
$result[] = (array) $one;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of list_course_module_competencies() result value.
|
||||
*
|
||||
* @return \external_description
|
||||
*/
|
||||
public static function list_course_module_competencies_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_single_structure(array(
|
||||
'competency' => competency_exporter::get_read_structure(),
|
||||
'coursemodulecompetency' => course_module_competency_exporter::get_read_structure()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of list_course_modules_using_competency() parameters.
|
||||
*
|
||||
* @return \external_function_parameters
|
||||
*/
|
||||
public static function list_course_modules_using_competency_parameters() {
|
||||
$competencyid = new external_value(
|
||||
PARAM_INT,
|
||||
'The competency id',
|
||||
VALUE_REQUIRED
|
||||
);
|
||||
$courseid = new external_value(
|
||||
PARAM_INT,
|
||||
'The course id',
|
||||
VALUE_REQUIRED
|
||||
);
|
||||
$params = array(
|
||||
'competencyid' => $competencyid,
|
||||
'courseid' => $courseid,
|
||||
);
|
||||
return new external_function_parameters($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the course modules using this competency (visible to this user) in this course.
|
||||
*
|
||||
* @param int $competencyid The competency id to check.
|
||||
* @param int $courseid The course id to check.
|
||||
* @return array
|
||||
*/
|
||||
public static function list_course_modules_using_competency($competencyid, $courseid) {
|
||||
global $PAGE;
|
||||
|
||||
$params = self::validate_parameters(self::list_course_modules_using_competency_parameters(),
|
||||
array(
|
||||
'competencyid' => $competencyid,
|
||||
'courseid' => $courseid,
|
||||
));
|
||||
|
||||
$coursecontext = context_course::instance($params['courseid']);
|
||||
self::validate_context($coursecontext);
|
||||
|
||||
$output = $PAGE->get_renderer('tool_lp');
|
||||
|
||||
$coursemodules = api::list_course_modules_using_competency($params['competencyid'], $params['courseid']);
|
||||
$result = array();
|
||||
|
||||
foreach ($coursemodules as $cmrecord) {
|
||||
$context = context_module::instance($cmrecord->id);
|
||||
$exporter = new course_module_summary_exporter($cmrecord, array('context' => $context));
|
||||
$coursemodulesummary = $exporter->export($output);
|
||||
|
||||
$result[] = $coursemodulesummary;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of list_course_modules_using_competency() result value.
|
||||
*
|
||||
* @return \external_description
|
||||
*/
|
||||
public static function list_course_modules_using_competency_returns() {
|
||||
return new external_multiple_structure(course_module_summary_exporter::get_read_structure());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of list_course_competencies() parameters.
|
||||
*
|
||||
|
@ -1741,6 +1877,7 @@ class external extends external_api {
|
|||
'competencies' => new external_multiple_structure(new external_single_structure(array(
|
||||
'competency' => competency_exporter::get_read_structure(),
|
||||
'coursecompetency' => course_competency_exporter::get_read_structure(),
|
||||
'coursemodules' => new external_multiple_structure(course_module_summary_exporter::get_read_structure()),
|
||||
'usercompetency' => $uc,
|
||||
'ruleoutcomeoptions' => new external_multiple_structure(
|
||||
new external_single_structure(array(
|
||||
|
|
38
admin/tool/lp/classes/external/course_module_competency_exporter.php
vendored
Normal file
38
admin/tool/lp/classes/external/course_module_competency_exporter.php
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class for exporting course module competency data.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_lp\external;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class for exporting course module competency data.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_module_competency_exporter extends persistent_exporter {
|
||||
|
||||
protected static function define_class() {
|
||||
return 'tool_lp\\course_module_competency';
|
||||
}
|
||||
}
|
78
admin/tool/lp/classes/external/course_module_summary_exporter.php
vendored
Normal file
78
admin/tool/lp/classes/external/course_module_summary_exporter.php
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Class for exporting a course module summary from an stdClass.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_lp\external;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use renderer_base;
|
||||
use moodle_url;
|
||||
|
||||
|
||||
/**
|
||||
* Class for exporting a course module summary from an stdClass.
|
||||
*
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class course_module_summary_exporter extends exporter {
|
||||
|
||||
protected function get_other_values(renderer_base $output) {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->libdir . '/modinfolib.php');
|
||||
|
||||
$cm = get_coursemodule_from_id(null, $this->data->id);
|
||||
$fastmodinfo = get_fast_modinfo($cm->course)->cms[$cm->id];
|
||||
|
||||
return array(
|
||||
'name' => $fastmodinfo->name,
|
||||
'url' => $fastmodinfo->url->out(),
|
||||
'iconurl' => $fastmodinfo->get_icon_url()->out()
|
||||
);
|
||||
}
|
||||
|
||||
public static function define_properties() {
|
||||
return array(
|
||||
'id' => array(
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'visible' => array(
|
||||
'type' => PARAM_BOOL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static function define_other_properties() {
|
||||
return array(
|
||||
'name' => array(
|
||||
'type' => PARAM_TEXT
|
||||
),
|
||||
'url' => array(
|
||||
'type' => PARAM_URL
|
||||
),
|
||||
'iconurl' => array(
|
||||
'type' => PARAM_URL
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
namespace tool_lp\external;
|
||||
|
||||
use tool_lp\api;
|
||||
use context_course;
|
||||
use renderer_base;
|
||||
use stdClass;
|
||||
|
@ -52,6 +53,10 @@ class user_competency_summary_in_course_exporter extends exporter {
|
|||
),
|
||||
'course' => array(
|
||||
'type' => course_summary_exporter::read_properties_definition(),
|
||||
),
|
||||
'coursemodules' => array(
|
||||
'type' => course_module_summary_exporter::read_properties_definition(),
|
||||
'multiple' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -70,6 +75,16 @@ class user_competency_summary_in_course_exporter extends exporter {
|
|||
$exporter = new course_summary_exporter($this->related['course'], array('context' => $context));
|
||||
$result->course = $exporter->export($output);
|
||||
|
||||
$coursemodules = api::list_course_modules_using_competency($this->related['competency']->get_id(),
|
||||
$this->related['course']->id);
|
||||
|
||||
$exportedmodules = array();
|
||||
foreach ($coursemodules as $cm) {
|
||||
$cmexporter = new course_module_summary_exporter($cm);
|
||||
$exportedmodules[] = $cmexporter->export($output);
|
||||
}
|
||||
$result->coursemodules = $exportedmodules;
|
||||
|
||||
return (array) $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ use tool_lp\course_competency;
|
|||
use tool_lp\competency;
|
||||
use tool_lp\external\competency_exporter;
|
||||
use tool_lp\external\course_competency_exporter;
|
||||
use tool_lp\external\course_module_summary_exporter;
|
||||
use tool_lp\external\user_competency_exporter;
|
||||
|
||||
/**
|
||||
|
@ -130,10 +131,19 @@ class course_competencies_page implements renderable, templatable {
|
|||
$ccoutcomeoptions = (array) (object) $ruleoutcomeoptions;
|
||||
$ccoutcomeoptions[$coursecompetency->get_ruleoutcome()]['selected'] = true;
|
||||
|
||||
$coursemodules = api::list_course_modules_using_competency($competency->get_id(), $this->courseid);
|
||||
|
||||
$exportedmodules = array();
|
||||
foreach ($coursemodules as $cm) {
|
||||
$cmexporter = new course_module_summary_exporter($cm);
|
||||
$exportedmodules[] = $cmexporter->export($output);
|
||||
}
|
||||
|
||||
$onerow = array(
|
||||
'competency' => $compexporter->export($output),
|
||||
'coursecompetency' => $ccexporter->export($output),
|
||||
'ruleoutcomeoptions' => $ccoutcomeoptions
|
||||
'ruleoutcomeoptions' => $ccoutcomeoptions,
|
||||
'coursemodules' => $exportedmodules
|
||||
);
|
||||
if ($gradable) {
|
||||
$foundusercompetency = false;
|
||||
|
|
|
@ -30,4 +30,8 @@ $observers = array(
|
|||
'eventname' => '\\core\\event\\course_completed',
|
||||
'callback' => '\\tool_lp\\api::observe_course_completed',
|
||||
),
|
||||
array(
|
||||
'eventname' => '\\core\\event\\course_module_completion_updated',
|
||||
'callback' => '\\tool_lp\\api::observe_course_module_completion_updated',
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="admin/tool/lp/db" VERSION="20160104" COMMENT="XMLDB file for Moodle admin/tool/lp"
|
||||
<XMLDB PATH="admin/tool/lp/db" VERSION="20160114" COMMENT="XMLDB file for Moodle admin/tool/lp"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
|
@ -278,5 +278,25 @@
|
|||
<INDEX NAME="userevidencecompids" UNIQUE="true" FIELDS="userevidenceid, competencyid"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
<TABLE NAME="tool_lp_module_competency" COMMENT="Link a competency to a module.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="cmid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the record in the course_modules table."/>
|
||||
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time this record was created."/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time this record was last modified"/>
|
||||
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The user who last modified this field."/>
|
||||
<FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The field used to naturally sort this link."/>
|
||||
<FIELD NAME="competencyid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The course competency this activity is linked to."/>
|
||||
<FIELD NAME="ruleoutcome" TYPE="int" LENGTH="2" NOTNULL="true" SEQUENCE="false" COMMENT="The outcome when an activity is completed."/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="cmidkey" TYPE="foreign" FIELDS="cmid" REFTABLE="id" REFFIELDS="course_modules" COMMENT="Foreign key on course modules table."/>
|
||||
<KEY NAME="competencyidkey" TYPE="foreign" FIELDS="competencyid" REFTABLE="tool_lp_competency" REFFIELDS="id" COMMENT="Foreign key on competency id."/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="cmidruleoutcome" UNIQUE="false" FIELDS="cmid, ruleoutcome" COMMENT="Index on cmid and outcome so we can quickly find what to do when an activity is completed."/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
||||
|
|
|
@ -651,6 +651,38 @@ function xmldb_tool_lp_upgrade($oldversion) {
|
|||
upgrade_plugin_savepoint(true, 2015111030, 'tool', 'lp');
|
||||
}
|
||||
|
||||
if ($oldversion < 2015111039) {
|
||||
|
||||
// Define table tool_lp_module_competency to be created.
|
||||
$table = new xmldb_table('tool_lp_module_competency');
|
||||
|
||||
// Adding fields to table tool_lp_module_competency.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
||||
$table->add_field('cmid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('competencyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
||||
$table->add_field('ruleoutcome', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null);
|
||||
|
||||
// Adding keys to table tool_lp_module_competency.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
||||
$table->add_key('cmidkey', XMLDB_KEY_FOREIGN, array('cmid'), 'id', array('course_modules'));
|
||||
$table->add_key('competencyidkey', XMLDB_KEY_FOREIGN, array('competencyid'), 'tool_lp_competency', array('id'));
|
||||
|
||||
// Adding indexes to table tool_lp_module_competency.
|
||||
$table->add_index('cmidruleoutcome', XMLDB_INDEX_NOTUNIQUE, array('cmid', 'ruleoutcome'));
|
||||
|
||||
// Conditionally launch create table for tool_lp_module_competency.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Lp savepoint reached.
|
||||
upgrade_plugin_savepoint(true, 2015111039, 'tool', 'lp');
|
||||
}
|
||||
|
||||
if ($oldversion < 2015111041) {
|
||||
|
||||
// Define field reviewerid to be added to tool_lp_plan.
|
||||
|
@ -666,6 +698,5 @@ function xmldb_tool_lp_upgrade($oldversion) {
|
|||
upgrade_plugin_savepoint(true, 2015111041, 'tool', 'lp');
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
$string['actions'] = 'Actions';
|
||||
$string['activities'] = 'Activities';
|
||||
$string['addcohorts'] = 'Add cohorts';
|
||||
$string['addcompetency'] = 'Add competency';
|
||||
$string['addingcompetencywillresetparentrule'] = 'Adding a new competency will remove the rule set on \'{$a}\'. Do you want to continue?';
|
||||
|
@ -69,6 +70,10 @@ $string['coursecompetencyoutcome_complete'] = 'Complete the competency';
|
|||
$string['coursecompetencyoutcome_evidence'] = 'Attach an evidence';
|
||||
$string['coursecompetencyoutcome_none'] = 'Do nothing';
|
||||
$string['coursecompetencyoutcome_recommend'] = 'Send for review';
|
||||
$string['coursemodulecompetencyoutcome_complete'] = 'Complete the competency';
|
||||
$string['coursemodulecompetencyoutcome_evidence'] = 'Attach an evidence';
|
||||
$string['coursemodulecompetencyoutcome_none'] = 'Do nothing';
|
||||
$string['coursemodulecompetencyoutcome_recommend'] = 'Send for review';
|
||||
$string['coursesusingthiscompetency'] = 'Courses linked to this competency';
|
||||
$string['coveragesummary'] = '{$a->competenciescoveredcount} of {$a->competenciescount} competencies are covered ( {$a->coveragepercentage} % )';
|
||||
$string['createplans'] = 'Create plans';
|
||||
|
@ -107,6 +112,7 @@ $string['eventtemplateviewed'] = 'Template viewed.';
|
|||
$string['evidence'] = 'Evidence';
|
||||
$string['evidence_competencyrule'] = 'The rule of the competency was met.';
|
||||
$string['evidence_coursecompleted'] = 'The course \'{$a}\' was completed.';
|
||||
$string['evidence_coursemodulecompleted'] = 'The activity \'{$a}\' was completed.';
|
||||
$string['evidence_evidenceofpriorlearninglinked'] = 'The evidence of prior learning \'{$a}\' was linked.';
|
||||
$string['evidence_evidenceofpriorlearningunlinked'] = 'The evidence of prior learning \'{$a}\' was unlinked.';
|
||||
$string['evidence_manualoverride'] = 'The competency rating was manually set.';
|
||||
|
@ -185,6 +191,8 @@ $string['lp:userevidenceread'] = 'View evidence of prior learning of a user';
|
|||
$string['managecompetenciesandframeworks'] = 'Manage competencies and frameworks';
|
||||
$string['messageprovider:user_competency_comment'] = 'Comment posted on a competency.';
|
||||
$string['messageprovider:plan_comment'] = 'Comment posted on a learning plan.';
|
||||
$string['modcompetencies'] = 'Course competencies';
|
||||
$string['modcompetencies_help'] = 'Course competencies linked to this activity.';
|
||||
$string['move'] = 'Move';
|
||||
$string['movecompetency'] = 'Move competency';
|
||||
$string['movecompetencyafter'] = 'Move competency after \'{$a}\'';
|
||||
|
@ -195,6 +203,7 @@ $string['moveframeworkafter'] = 'Move competency framework after \'{$a}\'';
|
|||
$string['movetonewparent'] = 'Relocate';
|
||||
$string['myplans'] = 'My plans';
|
||||
$string['nfiles'] = '{$a} file(s)';
|
||||
$string['noactivities'] = 'No activities';
|
||||
$string['nocompetencies'] = 'No competencies have been created in this framework.';
|
||||
$string['nocompetenciesincourse'] = 'No competencies have been linked to this course.';
|
||||
$string['nocompetenciesintemplate'] = 'No competencies have been linked to this template.';
|
||||
|
@ -346,6 +355,7 @@ $string['usercommentedonaplanhtml'] = '<p>{$a->fullname} commented on the plan "
|
|||
<p>See: <a href="{$a->url}">{$a->urlname}</a>.</p>';
|
||||
$string['usercommentedonaplansmall'] = '{$a->fullname} commented on the plan "{$a->plan}".';
|
||||
$string['usercommentedonaplansubject'] = '{$a} commented on a plan.';
|
||||
$string['uponcoursemodulecompletion'] = 'Upon activity completion:';
|
||||
$string['usercompetencystatus_idle'] = 'Idle';
|
||||
$string['usercompetencystatus_inreview'] = 'In review';
|
||||
$string['usercompetencystatus_waitingforreview'] = 'Waiting for review';
|
||||
|
|
|
@ -395,3 +395,62 @@ function tool_lp_comment_validate($params) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject the competencies elements into all moodle module settings forms.
|
||||
*
|
||||
* @param moodleform $formwrapper The moodle quickforms wrapper object.
|
||||
* @param MoodleQuickForm $mform The actual form object (required to modify the form).
|
||||
*/
|
||||
function tool_lp_coursemodule_standard_elements($formwrapper, $mform) {
|
||||
global $CFG, $COURSE;
|
||||
|
||||
$mform->addElement('header', 'competenciessection', get_string('competencies', 'tool_lp'));
|
||||
|
||||
MoodleQuickForm::registerElementType('course_competencies',
|
||||
"$CFG->dirroot/admin/tool/lp/classes/course_competencies_form_element.php",
|
||||
'tool_lp_course_competencies_form_element');
|
||||
$cmid = null;
|
||||
if ($cm = $formwrapper->get_coursemodule()) {
|
||||
$cmid = $cm->id;
|
||||
}
|
||||
$options = array(
|
||||
'courseid' => $COURSE->id,
|
||||
'cmid' => $cmid
|
||||
);
|
||||
$mform->addElement('course_competencies', 'competencies', get_string('modcompetencies', 'tool_lp'), $options);
|
||||
$mform->addHelpButton('competencies', 'modcompetencies', 'tool_lp');
|
||||
MoodleQuickForm::registerElementType('course_competency_rule',
|
||||
"$CFG->dirroot/admin/tool/lp/classes/course_competency_rule_form_element.php",
|
||||
'tool_lp_course_competency_rule_form_element');
|
||||
// Reuse the same options.
|
||||
$mform->addElement('course_competency_rule', 'competency_rule', get_string('uponcoursemodulecompletion', 'tool_lp'), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook the add/edit of the course module.
|
||||
*
|
||||
* @param stdClass $data Data from the form submission.
|
||||
*/
|
||||
function tool_lp_coursemodule_edit_post_actions($data, $course) {
|
||||
$existing = \tool_lp\api::list_course_module_competencies_in_course_module($data->coursemodule);
|
||||
|
||||
$getid = function($value) { return $value->get_competencyid(); };
|
||||
$existingids = array_map($getid, $existing);
|
||||
|
||||
$removed = array_diff($existingids, $data->competencies);
|
||||
$added = array_diff($data->competencies, $existingids);
|
||||
|
||||
foreach ($removed as $removedid) {
|
||||
\tool_lp\api::remove_competency_from_course_module($data->coursemodule, $removedid);
|
||||
}
|
||||
foreach ($added as $addedid) {
|
||||
\tool_lp\api::add_competency_to_course_module($data->coursemodule, $addedid);
|
||||
}
|
||||
|
||||
$current = \tool_lp\api::list_course_module_competencies_in_course_module($data->coursemodule);
|
||||
// Now update the rules for each course_module_competency.
|
||||
foreach ($current as $coursemodulecompetency) {
|
||||
\tool_lp\api::set_course_module_competency_ruleoutcome($coursemodulecompetency, $data->competency_rule);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,16 @@
|
|||
</label>
|
||||
</div>
|
||||
{{/canmanagecoursecompetencies}}
|
||||
<div data-region="coursecompetencyactivities">
|
||||
<ul class="inline">
|
||||
{{#coursemodules}}
|
||||
<li><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
|
||||
{{/coursemodules}}
|
||||
{{^coursemodules}}
|
||||
<li><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
|
||||
{{/coursemodules}}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/competencies}}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<input type="hidden" name="{{name}}" value="{{value}}"/>
|
|
@ -46,6 +46,17 @@
|
|||
{{> tool_lp/competency_summary }}
|
||||
{{/competency}}
|
||||
<dl>
|
||||
<dt>{{#str}}activities, tool_lp{{/str}}</dt>
|
||||
<dd data-region="coursecompetencyactivities">
|
||||
<ul class="inline">
|
||||
{{#coursemodules}}
|
||||
<li><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
|
||||
{{/coursemodules}}
|
||||
{{^coursemodules}}
|
||||
<li><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
|
||||
{{/coursemodules}}
|
||||
</ul>
|
||||
</dd>
|
||||
{{#usercompetency}}
|
||||
<dt>{{#str}}reviewstatus, tool_lp{{/str}}</dt>
|
||||
<dd data-region="user-competency-status">{{statusname}}
|
||||
|
|
|
@ -2318,6 +2318,76 @@ class tool_lp_api_testcase extends advanced_testcase {
|
|||
$this->assertEquals(null, $ev4->get_actionuserid());
|
||||
}
|
||||
|
||||
public function test_list_course_modules_using_competency() {
|
||||
global $SITE;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$dg = $this->getDataGenerator();
|
||||
$lpg = $dg->get_plugin_generator('tool_lp');
|
||||
$u1 = $dg->create_user();
|
||||
$u2 = $dg->create_user();
|
||||
$course = $dg->create_course();
|
||||
$course2 = $dg->create_course();
|
||||
|
||||
$this->setAdminUser();
|
||||
$f = $lpg->create_framework();
|
||||
$c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
|
||||
$c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
|
||||
$cc = api::add_competency_to_course($course->id, $c->get_id());
|
||||
$cc2 = api::add_competency_to_course($course->id, $c2->get_id());
|
||||
|
||||
// First check we get an empty list when there are no links.
|
||||
$expected = array();
|
||||
$result = api::list_course_modules_using_competency($c->get_id(), $course->id);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
|
||||
$page = $pagegenerator->create_instance(array('course'=>$course->id));
|
||||
|
||||
$cm = get_coursemodule_from_instance('page', $page->id);
|
||||
// Add a link and list again.
|
||||
$ccm = api::add_competency_to_course_module($cm, $c->get_id());
|
||||
$one = (object) array(
|
||||
'id' => $cm->id,
|
||||
'visible' => true
|
||||
);
|
||||
$expected = array($one);
|
||||
$result = api::list_course_modules_using_competency($c->get_id(), $course->id);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Check a different course.
|
||||
$expected = array();
|
||||
$result = api::list_course_modules_using_competency($c->get_id(), $course2->id);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Remove the link and check again.
|
||||
$result = api::remove_competency_from_course_module($cm, $c->get_id());
|
||||
$expected = true;
|
||||
$this->assertEquals($expected, $result);
|
||||
$expected = array();
|
||||
$result = api::list_course_modules_using_competency($c->get_id(), $course->id);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
// Now add 2 links.
|
||||
api::add_competency_to_course_module($cm, $c->get_id());
|
||||
api::add_competency_to_course_module($cm, $c2->get_id());
|
||||
$result = api::list_course_module_competencies_in_course_module($cm->id);
|
||||
$this->assertEquals($result[0]->get_competencyid(), $c->get_id());
|
||||
$this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
|
||||
|
||||
// Now re-order.
|
||||
api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
|
||||
$result = api::list_course_module_competencies_in_course_module($cm->id);
|
||||
$this->assertEquals($result[0]->get_competencyid(), $c2->get_id());
|
||||
$this->assertEquals($result[1]->get_competencyid(), $c->get_id());
|
||||
|
||||
// And re-order again.
|
||||
api::reorder_course_module_competency($cm, $c->get_id(), $c2->get_id());
|
||||
$result = api::list_course_module_competencies_in_course_module($cm->id);
|
||||
$this->assertEquals($result[0]->get_competencyid(), $c->get_id());
|
||||
$this->assertEquals($result[1]->get_competencyid(), $c2->get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test update ruleoutcome for course_competency.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue