MDL-53879 competency: Remove limit on framework depth
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
define(["jquery","core/ajax","core/str","tool_lp/competencypicker","core/templates","core/notification"],function(a,b,c,d,e,f){var g=function(a,b,c,d,e,f){this.buttonSelector=a,this.inputHiddenSelector=b,this.staticElementSelector=c,this.frameworkId=d,this.frameworkMaxLevel=e,this.pageContextId=f,this.registerEvents()};return g.prototype.buttonSelector=null,g.prototype.inputHiddenSelector=null,g.prototype.staticElementSelector=null,g.prototype.frameworkId=null,g.prototype.frameworkMaxLevel=null,g.prototype.pageContextId=null,g.prototype.setParent=function(d){var e=this;0!==d.competencyId?b.call([{methodname:"core_competency_read_competency",args:{id:d.competencyId}}])[0].done(function(b){a(e.staticElementSelector).html(b.shortname),a(e.inputHiddenSelector).val(b.id)}).fail(f.exception):c.get_string("competencyframeworkroot","tool_lp").then(function(b){a(e.staticElementSelector).html(b),a(e.inputHiddenSelector).val(d.competencyId)}).fail(f.exception)},g.prototype.registerEvents=function(){var c=this;a(c.buttonSelector).on("click",function(a){a.preventDefault();var g=new d(c.pageContextId,c.frameworkId,"self",!1),h=c.frameworkMaxLevel;g._fetchCompetencies=function(a,c){var d=this;return b.call([{methodname:"core_competency_search_competencies",args:{searchtext:c,competencyframeworkid:a}}])[0].done(function(a){function b(a,c){for(var d=0;d<c.length;d++){var e=String(c[d].path),g=e.split("/").length-2;g>=h&&"0"!==c[d].id&&f.push(c[d].id),c[d].parentid==a.id&&(a.haschildren=!0,c[d].children=[],c[d].haschildren=!1,a.children[a.children.length]=c[d],b(c[d],c))}}var c,e,f=[],g=[];for(c=0;c<a.length;c++)e=a[c],"0"==e.parentid&&(e.children=[],e.haschildren=0,g[g.length]=e,b(e,a));d._competencies=g,d.setDisallowedCompetencyIDs(f)}.bind(d)).fail(f.exception)},g._render=function(){var a=this;return a._preRender().then(function(){var b={competencies:a._competencies,framework:a._getFramework(a._frameworkId),frameworks:a._frameworks,search:a._searchText,singleFramework:a._singleFramework};return e.render("tool_lp/competency_picker_competencyform",b)}.bind(a))},g.on("save",function(a,b){c.setParent(b)}.bind(c)),g.display()})},{init:function(a,b,c,d,e,f){new g(a,b,c,d,e,f)}}});
|
||||
define(["jquery","core/ajax","core/str","tool_lp/competencypicker","core/templates","core/notification"],function(a,b,c,d,e,f){var g=function(a,b,c,d,e){this.buttonSelector=a,this.inputHiddenSelector=b,this.staticElementSelector=c,this.frameworkId=d,this.pageContextId=e,this.registerEvents()};return g.prototype.buttonSelector=null,g.prototype.inputHiddenSelector=null,g.prototype.staticElementSelector=null,g.prototype.frameworkId=null,g.prototype.pageContextId=null,g.prototype.setParent=function(d){var e=this;0!==d.competencyId?b.call([{methodname:"core_competency_read_competency",args:{id:d.competencyId}}])[0].done(function(b){a(e.staticElementSelector).html(b.shortname),a(e.inputHiddenSelector).val(b.id)}).fail(f.exception):c.get_string("competencyframeworkroot","tool_lp").then(function(b){a(e.staticElementSelector).html(b),a(e.inputHiddenSelector).val(d.competencyId)}).fail(f.exception)},g.prototype.registerEvents=function(){var b=this;a(b.buttonSelector).on("click",function(a){a.preventDefault();var c=new d(b.pageContextId,b.frameworkId,"self",!1);c._render=function(){var a=this;return a._preRender().then(function(){var b={competencies:a._competencies,framework:a._getFramework(a._frameworkId),frameworks:a._frameworks,search:a._searchText,singleFramework:a._singleFramework};return e.render("tool_lp/competency_picker_competencyform",b)}.bind(a))},c.on("save",function(a,c){b.setParent(c)}.bind(b)),c.display()})},{init:function(a,b,c,d,e){new g(a,b,c,d,e)}}});
|
||||
@@ -628,17 +628,6 @@ define(['jquery',
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return if the level has a sub level.
|
||||
*
|
||||
* @param {Number} level The level.
|
||||
* @return {Boolean}
|
||||
* @function hasSubLevel
|
||||
*/
|
||||
var hasSubLevel = function(level) {
|
||||
return typeof taxonomiesConstants[level + 1] !== 'undefined';
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the taxonomy constant for a level.
|
||||
*
|
||||
@@ -764,11 +753,7 @@ define(['jquery',
|
||||
var competency = treeModel.getCompetency(id);
|
||||
|
||||
level = treeModel.getCompetencyLevel(id);
|
||||
if (!hasSubLevel(level)) {
|
||||
sublevel = false;
|
||||
} else {
|
||||
sublevel = level + 1;
|
||||
}
|
||||
sublevel = level + 1;
|
||||
|
||||
actionMenu.show();
|
||||
$('[data-region="competencyactions"]').data('competency', competency);
|
||||
@@ -781,15 +766,12 @@ define(['jquery',
|
||||
selectedTitle.text(str);
|
||||
});
|
||||
|
||||
if (!sublevel) {
|
||||
btn.hide();
|
||||
} else {
|
||||
strAddTaxonomy(sublevel).then(function(str) {
|
||||
btn.show()
|
||||
.find('[data-region="term"]')
|
||||
.text(str);
|
||||
});
|
||||
}
|
||||
strAddTaxonomy(sublevel).then(function(str) {
|
||||
btn.show()
|
||||
.find('[data-region="term"]')
|
||||
.text(str);
|
||||
});
|
||||
|
||||
// We handled this event so consume it.
|
||||
evt.preventDefault();
|
||||
return false;
|
||||
|
||||
@@ -30,20 +30,17 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
|
||||
* @param {String} inputHiddenSelector The hidden input field selector.
|
||||
* @param {String} staticElementSelector The static element displaying the parent competency.
|
||||
* @param {Number} frameworkId The competency framework ID.
|
||||
* @param {Number} frameworkMaxLevel The framework max level.
|
||||
* @param {Number} pageContextId The page context ID.
|
||||
*/
|
||||
var ParentCompetencyForm = function(buttonSelector,
|
||||
inputHiddenSelector,
|
||||
staticElementSelector,
|
||||
frameworkId,
|
||||
frameworkMaxLevel,
|
||||
pageContextId) {
|
||||
this.buttonSelector = buttonSelector;
|
||||
this.inputHiddenSelector = inputHiddenSelector;
|
||||
this.staticElementSelector = staticElementSelector;
|
||||
this.frameworkId = frameworkId;
|
||||
this.frameworkMaxLevel = frameworkMaxLevel;
|
||||
this.pageContextId = pageContextId;
|
||||
|
||||
// Register the events.
|
||||
@@ -58,8 +55,6 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
|
||||
ParentCompetencyForm.prototype.staticElementSelector = null;
|
||||
/** @var {Number} The competency framework ID. */
|
||||
ParentCompetencyForm.prototype.frameworkId = null;
|
||||
/** @var {Number} The framework max level. */
|
||||
ParentCompetencyForm.prototype.frameworkMaxLevel = null;
|
||||
/** @var {Number} The page context ID. */
|
||||
ParentCompetencyForm.prototype.pageContextId = null;
|
||||
|
||||
@@ -103,55 +98,7 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
|
||||
e.preventDefault();
|
||||
|
||||
var picker = new Picker(self.pageContextId, self.frameworkId, 'self', false);
|
||||
var maxlevel = self.frameworkMaxLevel;
|
||||
// Override the fetchcompetencies method to filter by max level.
|
||||
picker._fetchCompetencies = function(frameworkId, searchText) {
|
||||
var self = this;
|
||||
|
||||
return ajax.call([
|
||||
{ methodname: 'core_competency_search_competencies', args: {
|
||||
searchtext: searchText,
|
||||
competencyframeworkid: frameworkId
|
||||
}}
|
||||
])[0].done(function(competencies) {
|
||||
|
||||
var disabledcompetencies = [];
|
||||
function addCompetencyChildren(parent, competencies) {
|
||||
for (var i = 0; i < competencies.length; i++) {
|
||||
// Check if competency does not exceed the framework max level.
|
||||
var path = String(competencies[i].path),
|
||||
level = path.split('/').length - 2;
|
||||
if (level >= maxlevel && competencies[i].id !== "0") {
|
||||
disabledcompetencies.push(competencies[i].id);
|
||||
}
|
||||
|
||||
if (competencies[i].parentid == parent.id) {
|
||||
parent.haschildren = true;
|
||||
competencies[i].children = [];
|
||||
competencies[i].haschildren = false;
|
||||
parent.children[parent.children.length] = competencies[i];
|
||||
addCompetencyChildren(competencies[i], competencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expand the list of competencies into a tree.
|
||||
var i, tree = [], comp;
|
||||
for (i = 0; i < competencies.length; i++) {
|
||||
comp = competencies[i];
|
||||
if (comp.parentid == "0") { // Loose check for now, because WS returns a string.
|
||||
comp.children = [];
|
||||
comp.haschildren = 0;
|
||||
tree[tree.length] = comp;
|
||||
addCompetencyChildren(comp, competencies);
|
||||
}
|
||||
}
|
||||
|
||||
self._competencies = tree;
|
||||
self.setDisallowedCompetencyIDs(disabledcompetencies);
|
||||
|
||||
}.bind(self)).fail(Notification.exception);
|
||||
};
|
||||
// Override the render method to make framework selectable.
|
||||
picker._render = function() {
|
||||
var self = this;
|
||||
@@ -185,7 +132,6 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
|
||||
* @param {String} inputHiddenSelector The hidden input field selector.
|
||||
* @param {String} staticElementSelector The static element displaying the parent competency.
|
||||
* @param {Number} frameworkId The competency framework ID.
|
||||
* @param {Number} frameworkMaxLevel The framework max level.
|
||||
* @param {Number} pageContextId The page context ID.
|
||||
* @method init
|
||||
*/
|
||||
@@ -193,14 +139,12 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
|
||||
inputSelector,
|
||||
staticElementSelector,
|
||||
frameworkId,
|
||||
frameworkMaxLevel,
|
||||
pageContextId) {
|
||||
// Create instance.
|
||||
new ParentCompetencyForm(buttonSelector,
|
||||
inputSelector,
|
||||
staticElementSelector,
|
||||
frameworkId,
|
||||
frameworkMaxLevel,
|
||||
pageContextId);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,7 +88,6 @@ class competency extends persistent {
|
||||
'#tool_lp_parentcompetency',
|
||||
'#id_parentdesc',
|
||||
$framework->get_id(),
|
||||
\core_competency\competency_framework::get_taxonomies_max_level(),
|
||||
$pagecontextid));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,8 @@ class competency_framework extends persistent {
|
||||
$mform->addElement('header', 'taxonomyhdr', get_string('taxonomies', 'tool_lp'));
|
||||
$taxonomies = \core_competency\competency_framework::get_taxonomies_list();
|
||||
$taxdefaults = array();
|
||||
for ($i = 1; $i <= \core_competency\competency_framework::get_taxonomies_max_level(); $i++) {
|
||||
$taxcount = max($framework ? $framework->get_depth() : 4, 4);
|
||||
for ($i = 1; $i <= $taxcount; $i++) {
|
||||
$mform->addElement('select', "taxonomies[$i]", get_string('levela', 'tool_lp', $i), $taxonomies);
|
||||
$taxdefaults[$i] = \core_competency\competency_framework::TAXONOMY_COMPETENCY;
|
||||
}
|
||||
|
||||
@@ -506,10 +506,6 @@ class competency extends persistent {
|
||||
} else if (!preg_match('@/([0-9]+/)+@', $value)) {
|
||||
// The format of the path is not correct.
|
||||
return new lang_string('invaliddata', 'error');
|
||||
|
||||
} else if ((substr_count($value, '/') - 1) > competency_framework::get_taxonomies_max_level()) {
|
||||
// Validate the depth of the path.
|
||||
return new lang_string('invaliddata', 'error');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -697,6 +693,29 @@ class competency extends persistent {
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current depth of a competency framework.
|
||||
*
|
||||
* @param int $frameworkid The framework ID.
|
||||
* @return int
|
||||
*/
|
||||
public static function get_framework_depth($frameworkid) {
|
||||
global $DB;
|
||||
$totallength = $DB->sql_length('path');
|
||||
$trimmedlength = $DB->sql_length("REPLACE(path, '/', '')");
|
||||
$sql = "SELECT ($totallength - $trimmedlength - 1) AS depth
|
||||
FROM {" . self::TABLE . "}
|
||||
WHERE competencyframeworkid = :id
|
||||
ORDER BY depth DESC";
|
||||
$record = $DB->get_record_sql($sql, array('id' => $frameworkid), IGNORE_MULTIPLE);
|
||||
if (!$record) {
|
||||
$depth = 0;
|
||||
} else {
|
||||
$depth = $record->depth;
|
||||
}
|
||||
return $depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a framework tree with competency nodes.
|
||||
*
|
||||
|
||||
@@ -133,6 +133,16 @@ class competency_framework extends persistent {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current depth of a competency framework.
|
||||
*
|
||||
* @see competency::get_framework_depth()
|
||||
* @return int
|
||||
*/
|
||||
public function get_depth() {
|
||||
return competency::get_framework_depth($this->get_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale.
|
||||
*
|
||||
@@ -176,8 +186,8 @@ class competency_framework extends persistent {
|
||||
unset($taxonomies[0]);
|
||||
|
||||
// Ensure that we do not return empty levels.
|
||||
for ($i = 1; $i <= self::get_taxonomies_max_level(); $i++) {
|
||||
if (empty($taxonomies[$i])) {
|
||||
foreach ($taxonomies as $i => $taxonomy) {
|
||||
if (empty($taxonomy)) {
|
||||
$taxonomies[$i] = self::TAXONOMY_COMPETENCY;
|
||||
}
|
||||
}
|
||||
@@ -335,10 +345,6 @@ class competency_framework extends persistent {
|
||||
protected function validate_taxonomies($value) {
|
||||
$terms = explode(',', $value);
|
||||
|
||||
if (count($terms) > self::get_taxonomies_max_level()) {
|
||||
return new lang_string('invaliddata', 'error');
|
||||
}
|
||||
|
||||
foreach ($terms as $term) {
|
||||
if (!empty($term) && !array_key_exists($term, self::get_taxonomies_list())) {
|
||||
return new lang_string('invalidtaxonomy', 'core_competency', $term);
|
||||
@@ -410,18 +416,6 @@ class competency_framework extends persistent {
|
||||
return self::get_taxonomies_list()[$constant];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of taxonomy levels.
|
||||
*
|
||||
* This is a method and not a constant because we want to make it easy to adapt
|
||||
* to the number of levels desired in the future.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function get_taxonomies_max_level() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of all taxonomies.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Competency tests.
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2016 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
|
||||
use core_competency\competency;
|
||||
|
||||
/**
|
||||
* Competency testcase.
|
||||
*
|
||||
* @package core_competency
|
||||
* @copyright 2016 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_competency_competency_testcase extends advanced_testcase {
|
||||
|
||||
public function test_get_framework_depth() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$ccg = $this->getDataGenerator()->get_plugin_generator('core_competency');
|
||||
$f1 = $ccg->create_framework();
|
||||
$f2 = $ccg->create_framework();
|
||||
$f3 = $ccg->create_framework();
|
||||
$f4 = $ccg->create_framework();
|
||||
|
||||
$f1c1 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id()]);
|
||||
$f1c11 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c1->get_id()]);
|
||||
$f1c111 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c11->get_id()]);
|
||||
$f1c1111 = $ccg->create_competency(['competencyframeworkid' => $f1->get_id(), 'parentid' => $f1c111->get_id()]);
|
||||
|
||||
$f2c1 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]);
|
||||
$f2c2 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]);
|
||||
$f2c21 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c2->get_id()]);
|
||||
$f2c22 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c2->get_id()]);
|
||||
$f2c211 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c21->get_id()]);
|
||||
$f2c221 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]);
|
||||
$f2c222 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]);
|
||||
$f2c223 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id(), 'parentid' => $f2c22->get_id()]);
|
||||
$f2c3 = $ccg->create_competency(['competencyframeworkid' => $f2->get_id()]);
|
||||
|
||||
$f3c1 = $ccg->create_competency(['competencyframeworkid' => $f3->get_id()]);
|
||||
|
||||
$this->assertEquals(4, competency::get_framework_depth($f1->get_id()));
|
||||
$this->assertEquals(3, competency::get_framework_depth($f2->get_id()));
|
||||
$this->assertEquals(1, competency::get_framework_depth($f3->get_id()));
|
||||
$this->assertEquals(0, competency::get_framework_depth($f4->get_id()));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user