From 71cb304ad841dbc604beefa964b6dbea1d8aee9f Mon Sep 17 00:00:00 2001 From: Serge Gauthier Date: Tue, 15 Mar 2016 17:05:43 -0400 Subject: [PATCH] MDL-53186 tool_lp: Send competencies in review from evidence interface --- .../build/competencypicker_user_plans.min.js | 2 +- .../lp/amd/build/user_evidence_actions.min.js | 2 +- .../lp/amd/src/competencypicker_user_plans.js | 24 +++ .../tool/lp/amd/src/user_evidence_actions.js | 77 +++++++++- admin/tool/lp/classes/api.php | 35 ++++- admin/tool/lp/classes/external.php | 61 ++++++-- ...r_evidence_competency_summary_exporter.php | 70 +++++++++ .../user_evidence_summary_exporter.php | 137 ++++++++++++++++++ .../output/user_evidence_list_page.php | 10 +- .../lp/classes/output/user_evidence_page.php | 13 +- admin/tool/lp/classes/user_evidence.php | 7 + .../lp/classes/user_evidence_competency.php | 27 ++++ admin/tool/lp/db/services.php | 9 ++ admin/tool/lp/lang/en/tool_lp.php | 5 +- .../competency_picker_user_plans.mustache | 4 + .../user_evidence_list_page.mustache | 15 +- .../lp/templates/user_evidence_page.mustache | 18 ++- .../tests/user_evidence_competency_test.php | 92 ++++++++++++ 18 files changed, 565 insertions(+), 43 deletions(-) create mode 100644 admin/tool/lp/classes/external/user_evidence_competency_summary_exporter.php create mode 100644 admin/tool/lp/classes/external/user_evidence_summary_exporter.php create mode 100644 admin/tool/lp/tests/user_evidence_competency_test.php diff --git a/admin/tool/lp/amd/build/competencypicker_user_plans.min.js b/admin/tool/lp/amd/build/competencypicker_user_plans.min.js index 1191fad69c2..01f38e6e9b4 100644 --- a/admin/tool/lp/amd/build/competencypicker_user_plans.min.js +++ b/admin/tool/lp/amd/build/competencypicker_user_plans.min.js @@ -1 +1 @@ -define(["jquery","core/notification","core/ajax","core/templates","core/str","tool_lp/tree","tool_lp/competencypicker"],function(a,b,c,d,e,f,g){var h=function(a,b,c){g.prototype.constructor.apply(this,[1,!1,"self",c]),this._userId=a,this._plans=[],b&&(this._planId=b,this._singlePlan=!0)};return h.prototype=Object.create(g.prototype),h.prototype._plans=null,h.prototype._planId=null,h.prototype._singlePlan=!1,h.prototype._userId=null,h.prototype._afterRender=function(){var b=this;g.prototype._afterRender.apply(b,arguments),b._singlePlan||b._find('[data-action="chooseplan"]').change(function(c){b._planId=a(c.target).val(),b._loadCompetencies().then(b._refresh.bind(b))}.bind(b))},h.prototype._fetchCompetencies=function(a,d){var e=this;return c.call([{methodname:"tool_lp_list_plan_competencies",args:{id:a}}])[0].done(function(a){var b,c,f=[];for(b=0;b0?a.when():(d=e._singlePlan?c.call([{methodname:"tool_lp_read_plan",args:{id:this._planId}}])[0].then(function(a){return[a]}):c.call([{methodname:"tool_lp_list_user_plans",args:{userid:e._userId}}])[0],d.done(function(a){e._plans=a}).fail(b.exception))},h.prototype._preRender=function(){var b=this;return b._loadPlans().then(function(){return!b._planId&&b._plans.length>0&&(b._planId=b._plans[0].id),b._planId?b._loadCompetencies():(b._plans=[],a.when())}.bind(b))},h.prototype._render=function(){var b=this;return b._preRender().then(function(){b._singlePlan||a.each(b._plans,function(a,c){c.id==b._planId?c.selected=!0:c.selected=!1});var c={competencies:b._competencies,plan:b._getPlan(b._planId),plans:b._plans,search:b._searchText,singlePlan:b._singlePlan};return d.render("tool_lp/competency_picker_user_plans",c)}.bind(b))},h}); \ No newline at end of file +define(["jquery","core/notification","core/ajax","core/templates","core/str","tool_lp/tree","tool_lp/competencypicker"],function(a,b,c,d,e,f,g){var h=function(a,b,c){g.prototype.constructor.apply(this,[1,!1,"self",c]),this._userId=a,this._plans=[],b&&(this._planId=b,this._singlePlan=!0)};return h.prototype=Object.create(g.prototype),h.prototype._plans=null,h.prototype._planId=null,h.prototype._singlePlan=!1,h.prototype._userId=null,h.prototype._requestReview=!1,h.prototype._afterRender=function(){var b=this;g.prototype._afterRender.apply(b,arguments),b._singlePlan||b._find('[data-action="chooseplan"]').change(function(c){b._planId=a(c.target).val(),b._loadCompetencies().then(b._refresh.bind(b))}.bind(b)),b._find('[data-action="request-review"]').change(function(c){b._requestReview=a(c.target).is(":checked"),b._refresh.bind(b)}.bind(b))},h.prototype._fetchCompetencies=function(a,d){var e=this;return c.call([{methodname:"tool_lp_list_plan_competencies",args:{id:a}}])[0].done(function(a){var b,c,f=[];for(b=0;b0?a.when():(d=e._singlePlan?c.call([{methodname:"tool_lp_read_plan",args:{id:this._planId}}])[0].then(function(a){return[a]}):c.call([{methodname:"tool_lp_list_user_plans",args:{userid:e._userId}}])[0],d.done(function(a){e._plans=a}).fail(b.exception))},h.prototype._preRender=function(){var b=this;return b._loadPlans().then(function(){return!b._planId&&b._plans.length>0&&(b._planId=b._plans[0].id),b._planId?b._loadCompetencies():(b._plans=[],a.when())}.bind(b))},h.prototype._render=function(){var b=this;return b._preRender().then(function(){b._singlePlan||a.each(b._plans,function(a,c){c.id==b._planId?c.selected=!0:c.selected=!1});var c={competencies:b._competencies,plan:b._getPlan(b._planId),plans:b._plans,search:b._searchText,singlePlan:b._singlePlan};return d.render("tool_lp/competency_picker_user_plans",c)}.bind(b))},h.prototype._trigger=function(a,b){var c=this;return"save"===a&&(b.requestReview=c._requestReview),g.prototype._trigger.apply(c,arguments)},h}); \ No newline at end of file diff --git a/admin/tool/lp/amd/build/user_evidence_actions.min.js b/admin/tool/lp/amd/build/user_evidence_actions.min.js index 3500cfdd5b6..10f9764290a 100644 --- a/admin/tool/lp/amd/build/user_evidence_actions.min.js +++ b/admin/tool/lp/amd/build/user_evidence_actions.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/ajax","core/notification","core/str","tool_lp/menubar","tool_lp/competencypicker_user_plans"],function(a,b,c,d,e,f,g){var h=function(a){if(this._type=a,"evidence"===a)this._region='[data-region="user-evidence-page"]',this._evidenceNode='[data-region="user-evidence-page"]',this._template="tool_lp/user_evidence_page",this._contextMethod="tool_lp_data_for_user_evidence_page";else{if("list"!==a)throw new TypeError("Unexpected type.");this._region='[data-region="user-evidence-list"]',this._evidenceNode='[data-region="user-evidence-node"]',this._template="tool_lp/user_evidence_list_page",this._contextMethod="tool_lp_data_for_user_evidence_list_page"}};return h.prototype._contextMethod=null,h.prototype._evidenceNode=null,h.prototype._region=null,h.prototype._template=null,h.prototype._type=null,h.prototype._getContextArgs=function(a){var b=this,c={};return"evidence"===b._type?c={id:a.id}:"list"===b._type&&(c={userid:a.userid}),c},h.prototype._renderView=function(c){var e=this;b.render(e._template,c).done(function(c,d){b.replaceNode(a(e._region),c,d)}.bind(e)).fail(d.exception)},h.prototype._callAndRefresh=function(b,e){var f=this;return b.push({methodname:f._contextMethod,args:f._getContextArgs(e)}),a.when.apply(a.when,c.call(b)).then(function(){f._renderView.call(f,arguments[arguments.length-1])}).fail(d.exception)},h.prototype._doDelete=function(a){var b=this,c=[{methodname:"tool_lp_delete_user_evidence",args:{id:a.id}}];b._callAndRefresh(c,a)},h.prototype.deleteEvidence=function(a){var b,f=this;b=c.call([{methodname:"tool_lp_read_user_evidence",args:{id:a.id}}]),b[0].done(function(b){e.get_strings([{key:"confirm",component:"moodle"},{key:"deleteuserevidence",component:"tool_lp",param:b.name},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(b){d.confirm(b[0],b[1],b[2],b[3],function(){f._doDelete(a)}.bind(f))}).fail(d.exception)}).fail(d.exception)},h.prototype._deleteEvidenceHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.deleteEvidence(c)},h.prototype._doCreateUserEvidenceCompetency=function(b,c){var d=this,e=[];a.each(c,function(a,c){e.push({methodname:"tool_lp_create_user_evidence_competency",args:{userevidenceid:b.id,competencyid:c}})}),d._callAndRefresh(e,b)},h.prototype.createUserEvidenceCompetency=function(a){var b=this,c=new g(a.userid);c.on("save",function(c,d){var e=d.competencyIds;b._doCreateUserEvidenceCompetency(a,e)}.bind(b)),c.display()},h.prototype._createUserEvidenceCompetencyHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.createUserEvidenceCompetency(c)},h.prototype._doDeleteUserEvidenceCompetency=function(a,b){var c=this,d=[];d.push({methodname:"tool_lp_delete_user_evidence_competency",args:{userevidenceid:a.id,competencyid:b}}),c._callAndRefresh(d,a)},h.prototype.deleteUserEvidenceCompetency=function(a,b){this._doDeleteUserEvidenceCompetency(a,b)},h.prototype._deleteUserEvidenceCompetencyHandler=function(b){var c=this._findEvidenceData(a(b.currentTarget)),d=a(b.currentTarget).data("id");b.preventDefault(),this.deleteUserEvidenceCompetency(c,d)},h.prototype._findEvidenceData=function(b){var c,d=b.parentsUntil(a(this._region).parent(),this._evidenceNode);if(1!=d.length)throw new Error("The evidence node was not located.");if(c=d.data(),"undefined"==typeof c||"undefined"==typeof c.id)throw new Error("Evidence data could not be found.");return c},h.prototype.enhanceMenubar=function(a){var b=this;f.enhance(a,{'[data-action="user-evidence-delete"]':b._deleteEvidenceHandler.bind(b),'[data-action="link-competency"]':b._createUserEvidenceCompetencyHandler.bind(b)})},h.prototype.registerEvents=function(){var b=a(this._region),c=this;b.find('[data-action="user-evidence-delete"]').click(c._deleteEvidenceHandler.bind(c)),b.find('[data-action="link-competency"]').click(c._createUserEvidenceCompetencyHandler.bind(c)),b.find('[data-action="delete-competency-link"]').click(c._deleteUserEvidenceCompetencyHandler.bind(c))},h}); \ No newline at end of file +define(["jquery","core/templates","core/ajax","core/notification","core/str","tool_lp/menubar","tool_lp/competencypicker_user_plans"],function(a,b,c,d,e,f,g){var h=function(a){if(this._type=a,"evidence"===a)this._region='[data-region="user-evidence-page"]',this._evidenceNode='[data-region="user-evidence-page"]',this._template="tool_lp/user_evidence_page",this._contextMethod="tool_lp_data_for_user_evidence_page";else{if("list"!==a)throw new TypeError("Unexpected type.");this._region='[data-region="user-evidence-list"]',this._evidenceNode='[data-region="user-evidence-node"]',this._template="tool_lp/user_evidence_list_page",this._contextMethod="tool_lp_data_for_user_evidence_list_page"}};return h.prototype._contextMethod=null,h.prototype._evidenceNode=null,h.prototype._region=null,h.prototype._template=null,h.prototype._type=null,h.prototype._getContextArgs=function(a){var b=this,c={};return"evidence"===b._type?c={id:a.id}:"list"===b._type&&(c={userid:a.userid}),c},h.prototype._renderView=function(c){var e=this;b.render(e._template,c).done(function(c,d){b.replaceNode(a(e._region),c,d)}.bind(e)).fail(d.exception)},h.prototype._callAndRefresh=function(b,e){var f=this;return b.push({methodname:f._contextMethod,args:f._getContextArgs(e)}),a.when.apply(a.when,c.call(b)).then(function(){f._renderView.call(f,arguments[arguments.length-1])}).fail(d.exception)},h.prototype._doDelete=function(a){var b=this,c=[{methodname:"tool_lp_delete_user_evidence",args:{id:a.id}}];b._callAndRefresh(c,a)},h.prototype.deleteEvidence=function(a){var b,f=this;b=c.call([{methodname:"tool_lp_read_user_evidence",args:{id:a.id}}]),b[0].done(function(b){e.get_strings([{key:"confirm",component:"moodle"},{key:"deleteuserevidence",component:"tool_lp",param:b.name},{key:"delete",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(b){d.confirm(b[0],b[1],b[2],b[3],function(){f._doDelete(a)}.bind(f))}).fail(d.exception)}).fail(d.exception)},h.prototype._deleteEvidenceHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.deleteEvidence(c)},h.prototype._doCreateUserEvidenceCompetency=function(b,c,d){var e=this,f=[];a.each(c,function(a,c){f.push({methodname:"tool_lp_create_user_evidence_competency",args:{userevidenceid:b.id,competencyid:c}}),d&&f.push({methodname:"tool_lp_user_competency_request_review",args:{userid:b.userid,competencyid:c,checkstatus:!1}})}),e._callAndRefresh(f,b)},h.prototype.createUserEvidenceCompetency=function(a){var b=this,c=new g(a.userid);c.on("save",function(c,d){var e=d.competencyIds;b._doCreateUserEvidenceCompetency(a,e,d.requestReview)}.bind(b)),c.display()},h.prototype._createUserEvidenceCompetencyHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.createUserEvidenceCompetency(c)},h.prototype._doDeleteUserEvidenceCompetency=function(a,b){var c=this,d=[];d.push({methodname:"tool_lp_delete_user_evidence_competency",args:{userevidenceid:a.id,competencyid:b}}),c._callAndRefresh(d,a)},h.prototype.deleteUserEvidenceCompetency=function(a,b){this._doDeleteUserEvidenceCompetency(a,b)},h.prototype._deleteUserEvidenceCompetencyHandler=function(b){var c=this._findEvidenceData(a(b.currentTarget)),d=a(b.currentTarget).data("id");b.preventDefault(),this.deleteUserEvidenceCompetency(c,d)},h.prototype._doReviewUserEvidenceCompetencies=function(a){var b=this,c=[{methodname:"tool_lp_request_review_of_user_evidence_linked_competencies",args:{id:a.id}}];b._callAndRefresh(c,a)},h.prototype.reviewUserEvidenceCompetencies=function(a){var b,f=this;b=c.call([{methodname:"tool_lp_read_user_evidence",args:{id:a.id}}]),b[0].done(function(b){e.get_strings([{key:"confirm",component:"moodle"},{key:"sendallcompetenciestoreview",component:"tool_lp",param:b.name},{key:"confirm",component:"moodle"},{key:"cancel",component:"moodle"}]).done(function(b){d.confirm(b[0],b[1],b[2],b[3],function(){f._doReviewUserEvidenceCompetencies(a)}.bind(f))}).fail(d.exception)}).fail(d.exception)},h.prototype._reviewUserEvidenceCompetenciesHandler=function(b){b.preventDefault();var c=this._findEvidenceData(a(b.target));this.reviewUserEvidenceCompetencies(c)},h.prototype._findEvidenceData=function(b){var c,d=b.parentsUntil(a(this._region).parent(),this._evidenceNode);if(1!=d.length)throw new Error("The evidence node was not located.");if(c=d.data(),"undefined"==typeof c||"undefined"==typeof c.id)throw new Error("Evidence data could not be found.");return c},h.prototype.enhanceMenubar=function(a){var b=this;f.enhance(a,{'[data-action="user-evidence-delete"]':b._deleteEvidenceHandler.bind(b),'[data-action="link-competency"]':b._createUserEvidenceCompetencyHandler.bind(b),'[data-action="send-competencies-review"]':b._reviewUserEvidenceCompetenciesHandler.bind(b)})},h.prototype.registerEvents=function(){var b=a(this._region),c=this;b.find('[data-action="user-evidence-delete"]').click(c._deleteEvidenceHandler.bind(c)),b.find('[data-action="link-competency"]').click(c._createUserEvidenceCompetencyHandler.bind(c)),b.find('[data-action="delete-competency-link"]').click(c._deleteUserEvidenceCompetencyHandler.bind(c)),b.find('[data-action="send-competencies-review"]').click(c._reviewUserEvidenceCompetenciesHandler.bind(c))},h}); \ No newline at end of file diff --git a/admin/tool/lp/amd/src/competencypicker_user_plans.js b/admin/tool/lp/amd/src/competencypicker_user_plans.js index b18b5ab5549..d97f3057e27 100644 --- a/admin/tool/lp/amd/src/competencypicker_user_plans.js +++ b/admin/tool/lp/amd/src/competencypicker_user_plans.js @@ -63,6 +63,8 @@ define(['jquery', Picker.prototype._singlePlan = false; /** @type {Number} The user the plans belongs to. */ Picker.prototype._userId = null; + /** @type {Boolean} Whether user want to send competencies to review. */ + Picker.prototype._requestReview = false; /** * Hook to executed after the view is rendered. @@ -81,6 +83,12 @@ define(['jquery', }.bind(self)); } + // Add listener for checkbox change. + self._find('[data-action="request-review"]').change(function(e) { + self._requestReview = $(e.target).is(":checked"); + self._refresh.bind(self); + }.bind(self)); + }; /** @@ -236,6 +244,22 @@ define(['jquery', }.bind(self)); }; + /** + * Trigger an event. + * + * @param {String} type The type of event. + * @param {Object} The data to pass to the listeners. + * @method _reset + */ + Picker.prototype._trigger = function(type, args) { + var self = this; + + if (type === 'save') { + args.requestReview = self._requestReview; + } + return PickerBase.prototype._trigger.apply(self, arguments); + }; + return /** @alias module:tool_lp/competencypicker_user_plans */ Picker; }); diff --git a/admin/tool/lp/amd/src/user_evidence_actions.js b/admin/tool/lp/amd/src/user_evidence_actions.js index d709cf992dd..f4091b3ea33 100644 --- a/admin/tool/lp/amd/src/user_evidence_actions.js +++ b/admin/tool/lp/amd/src/user_evidence_actions.js @@ -196,8 +196,9 @@ define(['jquery', * * @param {Object} evidenceData Evidence data from evidence node. * @param {Number} competencyIds The competency IDs. + * @param {Boolean} requestReview Send competencies to review. */ - UserEvidenceActions.prototype._doCreateUserEvidenceCompetency = function(evidenceData, competencyIds) { + UserEvidenceActions.prototype._doCreateUserEvidenceCompetency = function(evidenceData, competencyIds, requestReview) { var self = this, calls = []; @@ -209,6 +210,16 @@ define(['jquery', competencyid: competencyId, } }); + if (requestReview) { + calls.push({ + methodname: 'tool_lp_user_competency_request_review', + args: { + userid: evidenceData.userid, + competencyid: competencyId, + checkstatus: false + } + }); + } }); self._callAndRefresh(calls, evidenceData); @@ -225,7 +236,7 @@ define(['jquery', picker.on('save', function(e, data) { var competencyIds = data.competencyIds; - self._doCreateUserEvidenceCompetency(evidenceData, competencyIds); + self._doCreateUserEvidenceCompetency(evidenceData, competencyIds, data.requestReview); }.bind(self)); picker.display(); @@ -285,6 +296,66 @@ define(['jquery', this.deleteUserEvidenceCompetency(data, competencyId); }; + /** + * Send request review for user evidence competencies and reload the region. + * + * @param {Object} evidenceData Evidence data from evidence node. + */ + UserEvidenceActions.prototype._doReviewUserEvidenceCompetencies = function(evidenceData) { + var self = this, + calls = [{ + methodname: 'tool_lp_request_review_of_user_evidence_linked_competencies', + args: { id: evidenceData.id } + }]; + self._callAndRefresh(calls, evidenceData); + }; + + /** + * Send request review for user evidence competencies. + * + * @param {Object} evidenceData Evidence data from evidence node. + */ + UserEvidenceActions.prototype.reviewUserEvidenceCompetencies = function(evidenceData) { + var self = this, + requests; + + requests = ajax.call([{ + methodname: 'tool_lp_read_user_evidence', + args: { id: evidenceData.id } + }]); + + requests[0].done(function(evidence) { + str.get_strings([ + { key: 'confirm', component: 'moodle' }, + { key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name }, + { key: 'confirm', component: 'moodle' }, + { key: 'cancel', component: 'moodle' } + ]).done(function (strings) { + notification.confirm( + strings[0], // Confirm. + strings[1], // Send all competencies in review for X? + strings[2], // Confirm. + strings[3], // Cancel. + function() { + self._doReviewUserEvidenceCompetencies(evidenceData); + }.bind(self) + ); + }).fail(notification.exception); + }).fail(notification.exception); + + }; + + /** + * Send request review for user evidence competencies handler. + * + * @param {Event} e The event. + */ + UserEvidenceActions.prototype._reviewUserEvidenceCompetenciesHandler = function(e) { + e.preventDefault(); + var data = this._findEvidenceData($(e.target)); + this.reviewUserEvidenceCompetencies(data); + }; + /** * Find the evidence data from the evidence node. * @@ -317,6 +388,7 @@ define(['jquery', Menubar.enhance(selector, { '[data-action="user-evidence-delete"]': self._deleteEvidenceHandler.bind(self), '[data-action="link-competency"]': self._createUserEvidenceCompetencyHandler.bind(self), + '[data-action="send-competencies-review"]': self._reviewUserEvidenceCompetenciesHandler.bind(self), }); }; @@ -333,6 +405,7 @@ define(['jquery', wrapper.find('[data-action="user-evidence-delete"]').click(self._deleteEvidenceHandler.bind(self)); wrapper.find('[data-action="link-competency"]').click(self._createUserEvidenceCompetencyHandler.bind(self)); wrapper.find('[data-action="delete-competency-link"]').click(self._deleteUserEvidenceCompetencyHandler.bind(self)); + wrapper.find('[data-action="send-competencies-review"]').click(self._reviewUserEvidenceCompetenciesHandler.bind(self)); }; return /** @alias module:tool_lp/user_evidence_actions */ UserEvidenceActions; diff --git a/admin/tool/lp/classes/api.php b/admin/tool/lp/classes/api.php index b399158b305..53c228a76db 100644 --- a/admin/tool/lp/classes/api.php +++ b/admin/tool/lp/classes/api.php @@ -3346,9 +3346,10 @@ class api { * * @param int $userid The user ID. * @param int $competencyid The competency ID. + * @param bool $onlyidle Return exception if status is not idle. * @return bool */ - public static function user_competency_request_review($userid, $competencyid) { + public static function user_competency_request_review($userid, $competencyid, $onlyidle = true) { static::require_enabled(); $uc = user_competency::get_record(array('userid' => $userid, 'competencyid' => $competencyid)); if (!$uc) { @@ -3359,7 +3360,11 @@ class api { if (!$uc->can_read()) { throw new required_capability_exception($uc->get_context(), 'tool/lp:usercompetencyread', 'nopermissions', ''); } else if ($uc->get_status() != user_competency::STATUS_IDLE) { - throw new coding_exception('The competency can not be sent for review at this stage.'); + if ($onlyidle) { + throw new coding_exception('The competency can not be sent for review at this stage.'); + } else { + return true; + } } else if (!$uc->can_request_review()) { throw new required_capability_exception($uc->get_context(), 'tool/lp:usercompetencyrequestreview', 'nopermissions', ''); } @@ -3840,6 +3845,32 @@ class api { return $success; } + /** + * Send request review for user evidence competencies. + * + * @param int $id The user evidence ID. + * @return bool + */ + public static function request_review_of_user_evidence_linked_competencies($id) { + $onlyidle = false; + $userevidence = new user_evidence($id); + $context = $userevidence->get_context(); + $userid = $userevidence->get_userid(); + + if (!$userevidence->can_manage()) { + throw new required_capability_exception($context, 'tool/lp:userevidencemanage', 'nopermissions', ''); + } + + $usercompetencies = user_evidence_competency::get_user_competencies_by_userevidenceid($id); + foreach ($usercompetencies as $usercompetency) { + if ($usercompetency->get_status() == user_competency::STATUS_IDLE) { + static::user_competency_request_review($userid, $usercompetency->get_competencyid()); + } + } + + return true; + } + /** * Recursively duplicate competencies from a tree, we start duplicating from parents to children to have a correct path. * This method does not copy the related competencies. diff --git a/admin/tool/lp/classes/external.php b/admin/tool/lp/classes/external.php index d17ea2aece3..6b1a3668770 100644 --- a/admin/tool/lp/classes/external.php +++ b/admin/tool/lp/classes/external.php @@ -53,6 +53,7 @@ use tool_lp\external\user_competency_summary_exporter; use tool_lp\external\user_competency_summary_in_course_exporter; use tool_lp\external\user_competency_summary_in_plan_exporter; use tool_lp\external\user_evidence_exporter; +use tool_lp\external\user_evidence_summary_exporter; use tool_lp\external\user_evidence_competency_exporter; use tool_lp\external\competency_exporter; use tool_lp\external\course_competency_exporter; @@ -2940,7 +2941,7 @@ class external extends external_api { * @return boolean */ public static function user_competency_cancel_review_request($userid, $competencyid) { - $params = self::validate_parameters(self::user_competency_request_review_parameters(), array( + $params = self::validate_parameters(self::user_competency_cancel_review_request_parameters(), array( 'userid' => $userid, 'competencyid' => $competencyid )); @@ -2969,6 +2970,7 @@ class external extends external_api { return new external_function_parameters(array( 'userid' => new external_value(PARAM_INT, 'The user ID'), 'competencyid' => new external_value(PARAM_INT, 'The competency ID'), + 'checkstatus' => new external_value(PARAM_BOOL, 'Check status request', VALUE_DEFAULT, true) )); } @@ -2977,18 +2979,20 @@ class external extends external_api { * * @param int $userid The user ID. * @param int $competencyid The competency ID. + * @param boolean $checkstatus True to return exception when status is already in review. * @return boolean */ - public static function user_competency_request_review($userid, $competencyid) { + public static function user_competency_request_review($userid, $competencyid, $checkstatus) { $params = self::validate_parameters(self::user_competency_request_review_parameters(), array( 'userid' => $userid, - 'competencyid' => $competencyid + 'competencyid' => $competencyid, + 'checkstatus' => $checkstatus, )); $context = context_user::instance($params['userid']); self::validate_context($context); - return api::user_competency_request_review($userid, $competencyid); + return api::user_competency_request_review($userid, $competencyid, $checkstatus); } /** @@ -3020,7 +3024,7 @@ class external extends external_api { * @return boolean */ public static function user_competency_start_review($userid, $competencyid) { - $params = self::validate_parameters(self::user_competency_request_review_parameters(), array( + $params = self::validate_parameters(self::user_competency_start_review_parameters(), array( 'userid' => $userid, 'competencyid' => $competencyid )); @@ -3060,7 +3064,7 @@ class external extends external_api { * @return boolean */ public static function user_competency_stop_review($userid, $competencyid) { - $params = self::validate_parameters(self::user_competency_request_review_parameters(), array( + $params = self::validate_parameters(self::user_competency_stop_review_parameters(), array( 'userid' => $userid, 'competencyid' => $competencyid )); @@ -4063,9 +4067,7 @@ class external extends external_api { 'canmanage' => new external_value(PARAM_BOOL, 'Can the current user manage the user\'s evidence'), 'userid' => new external_value(PARAM_INT, 'The user ID'), 'pluginbaseurl' => new external_value(PARAM_LOCALURL, 'Url to the tool_lp plugin folder on this Moodle site'), - 'evidence' => new external_multiple_structure( - user_evidence_exporter::get_read_structure() - ), + 'evidence' => new external_multiple_structure(user_evidence_summary_exporter::get_read_structure()), 'navigation' => new external_multiple_structure( new external_value(PARAM_RAW, 'HTML for a navigation item that should be on this page') ), @@ -4109,8 +4111,8 @@ class external extends external_api { */ public static function data_for_user_evidence_page_returns() { return new external_single_structure(array( - 'userevidence' => user_evidence_exporter::get_read_structure(), - 'pluginbaseurl' => new external_value(PARAM_LOCALURL, 'Url to the tool_lp plugin folder on this Moodle site'), + 'userevidence' => user_evidence_summary_exporter::get_read_structure(), + 'pluginbaseurl' => new external_value(PARAM_LOCALURL, 'Url to the tool_lp plugin folder on this Moodle site') )); } @@ -4197,6 +4199,43 @@ class external extends external_api { return new external_value(PARAM_BOOL, 'True if the delete was successful'); } + /** + * Returns description of external function parameters. + * + * @return \external_function_parameters + */ + public static function request_review_of_user_evidence_linked_competencies_parameters() { + return new external_function_parameters(array( + 'id' => new external_value(PARAM_INT, 'The user evidence ID.') + )); + } + + /** + * Send user evidence competencies to review. + * + * @param int $id The user evidence id. + * @return boolean + */ + public static function request_review_of_user_evidence_linked_competencies($id) { + $params = self::validate_parameters(self::request_review_of_user_evidence_linked_competencies_parameters(), array( + 'id' => $id + )); + + $userevidence = api::read_user_evidence($id); + self::validate_context($userevidence->get_context()); + + return api::request_review_of_user_evidence_linked_competencies($id); + } + + /** + * Returns description of external function result value. + * + * @return \external_description + */ + public static function request_review_of_user_evidence_linked_competencies_returns() { + return new external_value(PARAM_BOOL, 'True if all competencies were send to review'); + } + /** * Returns the description of the get_scale_values() parameters. * diff --git a/admin/tool/lp/classes/external/user_evidence_competency_summary_exporter.php b/admin/tool/lp/classes/external/user_evidence_competency_summary_exporter.php new file mode 100644 index 00000000000..07f7da654bf --- /dev/null +++ b/admin/tool/lp/classes/external/user_evidence_competency_summary_exporter.php @@ -0,0 +1,70 @@ +. + +/** + * Class for exporting user evidence competency data. + * + * @package tool_lp + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace tool_lp\external; + +use moodle_url; +use renderer_base; + +/** + * Class for exporting user evidence competency data. + * + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class user_evidence_competency_summary_exporter extends exporter { + + protected static function define_related() { + return array('competency' => '\\tool_lp\\competency', + 'usercompetency' => '\\tool_lp\\user_competency', + 'scale' => 'grade_scale', + 'context' => '\\context' + ); + } + + protected static function define_other_properties() { + return array( + 'competency' => array( + 'type' => competency_exporter::read_properties_definition() + ), + 'usercompetency' => array( + 'type' => user_competency_exporter::read_properties_definition(), + ) + ); + } + + protected function get_other_values(renderer_base $output) { + $competencyexporter = new competency_exporter($this->related['competency'], + array('context' => $this->related['context'])); + $usercompetencyexporter = new user_competency_exporter($this->related['usercompetency'], + array('scale' => $this->related['scale'])); + + $values = array( + 'competency' => $competencyexporter->export($output), + 'usercompetency' => $usercompetencyexporter->export($output) + ); + + return $values; + } + +} diff --git a/admin/tool/lp/classes/external/user_evidence_summary_exporter.php b/admin/tool/lp/classes/external/user_evidence_summary_exporter.php new file mode 100644 index 00000000000..360e900e020 --- /dev/null +++ b/admin/tool/lp/classes/external/user_evidence_summary_exporter.php @@ -0,0 +1,137 @@ +. + +/** + * Class for exporting user evidence with all competencies. + * + * @package tool_lp + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace tool_lp\external; +defined('MOODLE_INTERNAL') || die(); + +use tool_lp\api; +use moodle_url; +use renderer_base; +use tool_lp\external\user_evidence_competency_summary_exporter; + +/** + * Class for exporting user evidence with all competencies. + * + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class user_evidence_summary_exporter extends persistent_exporter { + + protected static function define_class() { + return 'tool_lp\\user_evidence'; + } + + protected static function define_other_properties() { + return array( + 'canmanage' => array( + 'type' => PARAM_BOOL + ), + 'filecount' => array( + 'type' => PARAM_INT + ), + 'files' => array( + 'type' => stored_file_exporter::read_properties_definition(), + 'multiple' => true + ), + 'hasurlorfiles' => array( + 'type' => PARAM_BOOL + ), + 'urlshort' => array( + 'type' => PARAM_TEXT + ), + 'competencycount' => array( + 'type' => PARAM_INT + ), + 'usercompetencies' => array( + 'type' => user_evidence_competency_summary_exporter::read_properties_definition(), + 'optional' => true, + 'multiple' => true + ), + ); + } + + protected function get_other_values(renderer_base $output) { + $urlshort = ''; + $url = $this->persistent->get_url(); + if (!empty($url)) { + $murl = new moodle_url($url); + $shorturl = preg_replace('@^https?://(www\.)?@', '', $murl->out(false)); + $urlshort = shorten_text($shorturl, 30, true); + } + + $files = array(); + $storedfiles = $this->persistent->get_files(); + if (!empty($storedfiles)) { + foreach ($storedfiles as $storedfile) { + $fileexporter = new stored_file_exporter($storedfile, array('context' => $this->related['context'])); + $files[] = $fileexporter->export($output); + } + } + + $userevidencecompetencies = array(); + $frameworks = array(); + $scales = array(); + $usercompetencies = $this->persistent->get_user_competencies(); + foreach ($usercompetencies as $usercompetency) { + $competency = $usercompetency->get_competency(); + + // Get the framework. + if (!isset($frameworks[$competency->get_competencyframeworkid()])) { + $frameworks[$competency->get_competencyframeworkid()] = $competency->get_framework(); + } + $framework = $frameworks[$competency->get_competencyframeworkid()]; + + // Get the scale. + $scaleid = $competency->get_scaleid(); + if ($scaleid === null) { + $scaleid = $framework->get_scaleid(); + } + if (!isset($scales[$framework->get_scaleid()])) { + $scales[$framework->get_scaleid()] = $framework->get_scale(); + } + $scale = $scales[$framework->get_scaleid()]; + + $related = array('competency' => $competency, + 'usercompetency' => $usercompetency, + 'scale' => $scale, + 'context' => $framework->get_context()); + + $userevidencecompetencysummaryexporter = new user_evidence_competency_summary_exporter(null, $related); + + $userevidencecompetencies[] = $userevidencecompetencysummaryexporter->export($output); + } + + $values = array( + 'canmanage' => $this->persistent->can_manage(), + 'filecount' => count($files), + 'files' => $files, + 'hasurlorfiles' => !empty($files) || !empty($url), + 'urlshort' => $urlshort, + 'competencycount' => count($userevidencecompetencies), + 'usercompetencies' => $userevidencecompetencies + ); + + return $values; + } + +} diff --git a/admin/tool/lp/classes/output/user_evidence_list_page.php b/admin/tool/lp/classes/output/user_evidence_list_page.php index 73a4fcdeeaf..4f22eb1ee94 100644 --- a/admin/tool/lp/classes/output/user_evidence_list_page.php +++ b/admin/tool/lp/classes/output/user_evidence_list_page.php @@ -30,7 +30,7 @@ use stdClass; use single_button; use moodle_url; use tool_lp\api; -use tool_lp\external\user_evidence_exporter; +use tool_lp\external\user_evidence_summary_exporter; use tool_lp\user_evidence; use context_user; @@ -93,12 +93,10 @@ class user_evidence_list_page implements renderable, templatable { $data->evidence = array(); if ($this->evidence) { foreach ($this->evidence as $evidence) { - $evidenceexporter = new user_evidence_exporter($evidence, array( - 'context' => $this->context, - 'competencies' => $evidence->get_competencies() + $userevidencesummaryexporter = new user_evidence_summary_exporter($evidence, array( + 'context' => $this->context )); - $record = $evidenceexporter->export($output); - $data->evidence[] = $record; + $data->evidence[] = $userevidencesummaryexporter->export($output); } } diff --git a/admin/tool/lp/classes/output/user_evidence_page.php b/admin/tool/lp/classes/output/user_evidence_page.php index 54e53dacd25..1ba5347cb02 100644 --- a/admin/tool/lp/classes/output/user_evidence_page.php +++ b/admin/tool/lp/classes/output/user_evidence_page.php @@ -28,8 +28,7 @@ use renderable; use templatable; use stdClass; use tool_lp\api; -use tool_lp\external\competency_exporter; -use tool_lp\external\user_evidence_exporter; +use tool_lp\external\user_evidence_summary_exporter; /** * User evidence page class. @@ -64,12 +63,12 @@ class user_evidence_page implements renderable, templatable { */ public function export_for_template(\renderer_base $output) { $data = new stdClass(); - $evidenceexporter = new user_evidence_exporter($this->userevidence, array( - 'context' => $this->context, - 'competencies' => $this->userevidence->get_competencies() - )); - $data->userevidence = $evidenceexporter->export($output); + + $userevidencesummaryexporter = new user_evidence_summary_exporter($this->userevidence, array( + 'context' => $this->context)); + $data->userevidence = $userevidencesummaryexporter->export($output); $data->pluginbaseurl = (new moodle_url('/admin/tool/lp'))->out(true); + return $data; } } diff --git a/admin/tool/lp/classes/user_evidence.php b/admin/tool/lp/classes/user_evidence.php index 823765e10e9..5f992b8314c 100644 --- a/admin/tool/lp/classes/user_evidence.php +++ b/admin/tool/lp/classes/user_evidence.php @@ -103,6 +103,13 @@ class user_evidence extends persistent { return user_evidence_competency::get_competencies_by_userevidenceid($this->get_id()); } + /** + * Get link user competencies. + */ + public function get_user_competencies() { + return user_evidence_competency::get_user_competencies_by_userevidenceid($this->get_id()); + } + /** * Return the files associated with this evidence. * diff --git a/admin/tool/lp/classes/user_evidence_competency.php b/admin/tool/lp/classes/user_evidence_competency.php index 88599c90c89..15ced479ea9 100644 --- a/admin/tool/lp/classes/user_evidence_competency.php +++ b/admin/tool/lp/classes/user_evidence_competency.php @@ -105,6 +105,33 @@ class user_evidence_competency extends persistent { return $competencies; } + /** + * Get user competencies by user evidence ID. + * + * @param int $userevidenceid The user evidence ID. + * @return user_competency[] + */ + public static function get_user_competencies_by_userevidenceid($userevidenceid) { + global $DB; + + $sql = "SELECT uc.* + FROM {" . user_competency::TABLE . "} uc + JOIN {" . self::TABLE . "} uec + ON uc.competencyid = uec.competencyid + JOIN {" . user_evidence::TABLE . "} ue + ON uec.userevidenceid = ue.id + AND uc.userid = ue.userid + AND ue.id = ?"; + + $usercompetencies = array(); + $records = $DB->get_recordset_sql($sql, array($userevidenceid)); + foreach ($records as $record) { + $usercompetencies[] = new user_competency(0, $record); + } + $records->close(); + return $usercompetencies; + } + /** * Get a relation. * diff --git a/admin/tool/lp/db/services.php b/admin/tool/lp/db/services.php index 98f8cab80b2..946bca083c7 100644 --- a/admin/tool/lp/db/services.php +++ b/admin/tool/lp/db/services.php @@ -890,5 +890,14 @@ $functions = array( 'capabilities' => 'tool/lp:templateread', 'ajax' => true, ), + 'tool_lp_request_review_of_user_evidence_linked_competencies' => array( + 'classname' => 'tool_lp\external', + 'methodname' => 'request_review_of_user_evidence_linked_competencies', + 'classpath' => '', + 'description' => 'Send user evidence competencies in review', + 'type' => 'write', + 'capabilities' => 'tool/lp:userevidencemanageown', + 'ajax' => true, + ), ); diff --git a/admin/tool/lp/lang/en/tool_lp.php b/admin/tool/lp/lang/en/tool_lp.php index 09429fdb84c..724b7b1c50d 100644 --- a/admin/tool/lp/lang/en/tool_lp.php +++ b/admin/tool/lp/lang/en/tool_lp.php @@ -292,6 +292,7 @@ $string['reviewstatus'] = 'Review status'; $string['requestreview'] = 'Request review'; $string['reopenplan'] = 'Reopen this learning plan'; $string['reopenplanconfirm'] = 'Reopen the plan \'{$a}\'? The status of the users competencies that was recorded at the time the plan was previously completed will be deleted, and the plan will become active again.'; +$string['reviewer'] = 'Reviewer'; $string['savechanges'] = 'Save changes'; $string['scale'] = 'Scale'; $string['scale_help'] = 'A scale determines how proficiency is measured in a competency. After selecting a scale, configure the scale, setting one of the scale values as default and marking all scale values that are deemed proficient.'; @@ -301,6 +302,8 @@ $string['selectcompetencymovetarget'] = 'Select a location to move this competen $string['selectedcompetency'] = 'Selected competency'; $string['selectcohortstosync'] = 'Select cohorts to sync'; $string['selectuserstocreateplansfor'] = 'Select users to create plans for'; +$string['sendcompetenciestoreview'] = 'Send competencies for review'; +$string['sendallcompetenciestoreview'] = 'Send all competencies in review for evidence of prior learning \'{$a}\''; $string['shortname'] = 'Name'; $string['startreview'] = 'Start review'; $string['state'] = 'State'; @@ -412,7 +415,7 @@ $string['userevidencecreated'] = 'Evidence of prior learning created'; $string['userevidencedescription'] = 'Description'; $string['userevidencefiles'] = 'Files'; $string['userevidencename'] = 'Name'; -$string['userevidenceummary'] = 'Summary'; +$string['userevidencesummary'] = 'Summary'; $string['userevidenceupdated'] = 'Evidence of prior learning updated'; $string['userevidenceurl'] = 'URL'; $string['userplans'] = 'User plans'; diff --git a/admin/tool/lp/templates/competency_picker_user_plans.mustache b/admin/tool/lp/templates/competency_picker_user_plans.mustache index 1e052b94172..9e96fe8c8b6 100644 --- a/admin/tool/lp/templates/competency_picker_user_plans.mustache +++ b/admin/tool/lp/templates/competency_picker_user_plans.mustache @@ -27,6 +27,10 @@
+
+ + +
diff --git a/admin/tool/lp/templates/user_evidence_list_page.mustache b/admin/tool/lp/templates/user_evidence_list_page.mustache index ff68421a1e5..d89b16e3638 100644 --- a/admin/tool/lp/templates/user_evidence_list_page.mustache +++ b/admin/tool/lp/templates/user_evidence_list_page.mustache @@ -39,8 +39,8 @@ {{#str}}userevidencename, tool_lp{{/str}} - {{#str}}userevidenceummary, tool_lp{{/str}} - {{#str}}linkedcompetencies, tool_lp{{/str}} + {{#str}}userevidencesummary, tool_lp{{/str}} + {{#str}}linkedcompetencies, tool_lp{{/str}} ({{#str}}status, tool_lp{{/str}} / {{#str}}reviewer, tool_lp{{/str}}) {{#canmanage}} {{#str}}actions, tool_lp{{/str}} {{/canmanage}} @@ -71,11 +71,11 @@ {{/competencycount}} {{#competencycount}}
    - {{#competencies}} + {{#usercompetencies}}
  • - {{shortname}} {{idnumber}} + {{competency.shortname}} {{competency.idnumber}} ({{usercompetency.statusname}}{{#usercompetency.reviewer.fullname}} / {{usercompetency.reviewer.fullname}}{{/usercompetency.reviewer.fullname}})
  • - {{/competencies}} + {{/usercompetencies}}
{{/competencycount}} @@ -96,6 +96,11 @@ {{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}} +
  • + + {{#pix}}t/edit{{/pix}} {{#str}}sendcompetenciestoreview, tool_lp{{/str}} + +
  • {{#pix}}t/delete{{/pix}} {{#str}}deletethisuserevidence, tool_lp{{/str}} diff --git a/admin/tool/lp/templates/user_evidence_page.mustache b/admin/tool/lp/templates/user_evidence_page.mustache index 6a6ab4875d4..bebd9ce721d 100644 --- a/admin/tool/lp/templates/user_evidence_page.mustache +++ b/admin/tool/lp/templates/user_evidence_page.mustache @@ -59,26 +59,30 @@ {{#str}}shortname, tool_lp{{/str}} - {{#userevidence.canmanage}} + {{#str}}status, tool_lp{{/str}} / {{#str}}reviewer, tool_lp{{/str}} + {{#canmanage}} {{#str}}actions, tool_lp{{/str}} - {{/userevidence.canmanage}} + {{/canmanage}} - {{#competencies}} - + {{#usercompetencies}} + - {{shortname}} + {{competency.shortname}} + + + {{usercompetency.statusname}} {{#usercompetency.reviewer.fullname}} / {{usercompetency.reviewer.fullname}}{{/usercompetency.reviewer.fullname}} {{#userevidence.canmanage}} {{/userevidence.canmanage}} - {{/competencies}} + {{/usercompetencies}} diff --git a/admin/tool/lp/tests/user_evidence_competency_test.php b/admin/tool/lp/tests/user_evidence_competency_test.php new file mode 100644 index 00000000000..72621174f85 --- /dev/null +++ b/admin/tool/lp/tests/user_evidence_competency_test.php @@ -0,0 +1,92 @@ +. + +/** + * User evidence competency persistent class tests. + * + * @package tool_lp + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +use tool_lp\user_evidence_competency; + +/** + * User evidence competency persistent testcase. + * + * @package tool_lp + * @copyright 2016 Serge Gauthier - + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class tool_lp_user_evidene_competency_testcase extends advanced_testcase { + + public function test_get_user_competencies_by_userevidenceid() { + global $CFG, $DB; + + $this->resetAfterTest(true); + $dg = $this->getDataGenerator(); + $lpg = $dg->get_plugin_generator('tool_lp'); + + $u1 = $dg->create_user(); + + // Create framework with competencies. + $fw = $lpg->create_framework(); + $c1 = $lpg->create_competency(array('competencyframeworkid' => $fw->get_id())); + $c2 = $lpg->create_competency(array('competencyframeworkid' => $fw->get_id())); + $c3 = $lpg->create_competency(array('competencyframeworkid' => $fw->get_id())); + $c4 = $lpg->create_competency(array('competencyframeworkid' => $fw->get_id())); + + // Create a plan with competencies. + $p1 = $lpg->create_plan(array('userid' => $u1->id)); + $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c1->get_id())); + $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c2->get_id())); + $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c3->get_id())); + $lpg->create_plan_competency(array('planid' => $p1->get_id(), 'competencyid' => $c4->get_id())); + + // Create a prior learning evidence and link competencies. + $ue1 = $lpg->create_user_evidence(array('userid' => $u1->id)); + $uec11 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get_id(), 'competencyid' => $c1->get_id())); + $uec12 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get_id(), 'competencyid' => $c2->get_id())); + $uec13 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue1->get_id(), 'competencyid' => $c3->get_id())); + $uc11 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c1->get_id())); + $uc12 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c2->get_id())); + $uc13 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c3->get_id())); + + // Create an other prior learning evidence and link competencies. + $ue2 = $lpg->create_user_evidence(array('userid' => $u1->id)); + $uec22 = $lpg->create_user_evidence_competency(array('userevidenceid' => $ue2->get_id(), 'competencyid' => $c4->get_id())); + $uc22 = $lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $c4->get_id())); + + // Check the user competencies associated to the first prior learning evidence. + $ucs = user_evidence_competency::get_user_competencies_by_userevidenceid($ue1->get_id()); + $this->assertCount(3, $ucs); + $uc = array_shift($ucs); + $this->assertEquals($uc->get_id(), $uc11->get_id()); + $uc = array_shift($ucs); + $this->assertEquals($uc->get_id(), $uc12->get_id()); + $uc = array_shift($ucs); + $this->assertEquals($uc->get_id(), $uc13->get_id()); + + // Check the user competencies associated to the second prior learning evidence. + $ucs = user_evidence_competency::get_user_competencies_by_userevidenceid($ue2->get_id()); + $this->assertCount(1, $ucs); + $uc = array_shift($ucs); + $this->assertEquals($uc->get_id(), $uc22->get_id()); + } +}