MDL-51042 tool_lp: Add useful statistics to the template competencies page.

This commit is contained in:
Damyon Wiese
2016-04-18 10:58:56 +08:00
committed by Frederic Massart
parent b986597039
commit 3edcd295eb
13 changed files with 730 additions and 22 deletions
+130 -11
View File
@@ -1989,41 +1989,66 @@ class api {
/**
* Count all the competencies in a learning plan template.
*
* @param int $templateid The id of the template to check.
* @param template|int $templateorid The template or its ID.
* @return int
*/
public static function count_competencies_in_template($templateid) {
public static function count_competencies_in_template($templateorid) {
static::require_enabled();
// First we do a permissions check.
$template = new template($templateid);
$context = $template->get_context();
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
// OK - all set.
return template_competency::count_competencies($templateid);
return template_competency::count_competencies($template->get_id());
}
/**
* Count all the competencies in a learning plan template with no linked courses.
*
* @param template|int $templateorid The template or its ID.
* @return int
*/
public static function count_competencies_in_template_with_no_courses($templateorid) {
// First we do a permissions check.
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
// OK - all set.
return template_competency::count_competencies_with_no_courses($template->get_id());
}
/**
* List all the competencies in a template.
*
* @param int $templateid The id of the template to check.
* @param template|int $templateorid The template or its ID.
* @return array of competencies
*/
public static function list_competencies_in_template($templateid) {
public static function list_competencies_in_template($templateorid) {
static::require_enabled();
// First we do a permissions check.
$template = new template($templateid);
$context = $template->get_context();
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
// OK - all set.
return template_competency::list_competencies($templateid);
return template_competency::list_competencies($template->get_id());
}
/**
@@ -3516,7 +3541,6 @@ class api {
// OK - all set.
return $template->has_plans();
}
/**
@@ -4680,6 +4704,101 @@ class api {
return $result;
}
/**
* Count the plans in the template, filtered by status.
*
* Requires tool/lp:templateread capability at the system context.
*
* @param mixed $templateorid The id or the template.
* @param int $status One of the plan status constants (or 0 for all plans).
* @return int
*/
public static function count_plans_for_template($templateorid, $status = 0) {
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
// First we do a permissions check.
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
return plan::count_records_for_template($template->get_id(), $status);
}
/**
* Count the user-completency-plans in the template, optionally filtered by proficiency.
*
* Requires tool/lp:templateread capability at the system context.
*
* @param mixed $templateorid The id or the template.
* @param mixed $proficiency If true, filter by proficiency, if false filter by not proficient, if null - no filter.
* @return int
*/
public static function count_user_competency_plans_for_template($templateorid, $proficiency = null) {
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
// First we do a permissions check.
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
return user_competency_plan::count_records_for_template($template->get_id(), $proficiency);
}
/**
* List the plans in the template, filtered by status.
*
* Requires tool/lp:templateread capability at the system context.
*
* @param mixed $templateorid The id or the template.
* @param int $status One of the plan status constants (or 0 for all plans).
* @param int $skip The number of records to skip
* @param int $limit The max number of records to return
* @return plan[]
*/
public static function list_plans_for_template($templateorid, $status = 0, $skip = 0, $limit = 100) {
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
// First we do a permissions check.
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
return plan::get_records_for_template($template->get_id(), $status, $skip, $limit);
}
/**
* Get the most often not completed competency for this template.
*
* Requires tool/lp:templateread capability at the system context.
*
* @param mixed $templateorid The id or the template.
* @param int $skip The number of records to skip
* @param int $limit The max number of records to return
* @return competency[]
*/
public static function get_least_proficient_competencies_for_template($templateorid, $skip = 0, $limit = 100) {
$template = $templateorid;
if (!is_object($template)) {
$template = new template($template);
}
// First we do a permissions check.
if (!$template->can_read()) {
throw new required_capability_exception($template->get_context(), 'tool/lp:templateread', 'nopermissions', '');
}
return user_competency_plan::get_least_proficient_competencies_for_template($template->get_id(), $skip, $limit);
}
/**
* Template event viewed.
*
+2
View File
@@ -45,6 +45,7 @@ use grade_scale;
use tool_lp\external\competency_framework_exporter;
use tool_lp\external\competency_summary_exporter;
use tool_lp\external\cohort_summary_exporter;
use tool_lp\external\template_statistics_exporter;
use tool_lp\external\user_summary_exporter;
use tool_lp\external\user_competency_exporter;
use tool_lp\external\user_competency_plan_exporter;
@@ -3203,6 +3204,7 @@ class external extends external_api {
competency_summary_exporter::get_read_structure()
),
'manageurl' => new external_value(PARAM_LOCALURL, 'Url to the manage competencies page.'),
'statistics' => template_statistics_exporter::get_read_structure()
));
}
@@ -0,0 +1,125 @@
<?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 template statistics summary.
*
* @package tool_lp
* @copyright 2016 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 cohort summary from an stdClass.
*
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class template_statistics_exporter extends exporter {
public static function define_properties() {
return array(
'competencycount' => array(
'type' => PARAM_INT,
),
'unlinkedcompetencycount' => array(
'type' => PARAM_INT,
),
'plancount' => array(
'type' => PARAM_INT,
),
'completedplancount' => array(
'type' => PARAM_INT,
),
'usercompetencyplancount' => array(
'type' => PARAM_INT,
),
'proficientusercompetencyplancount' => array(
'type' => PARAM_INT,
)
);
}
public static function define_other_properties() {
return array(
'linkedcompetencypercentage' => array(
'type' => PARAM_FLOAT
),
'linkedcompetencycount' => array(
'type' => PARAM_INT
),
'completedplanpercentage' => array(
'type' => PARAM_FLOAT
),
'proficientusercompetencyplanpercentage' => array(
'type' => PARAM_FLOAT
),
'leastproficient' => array(
'type' => competency_exporter::read_properties_definition(),
'multiple' => true
),
'leastproficientcount' => array(
'type' => PARAM_INT
),
);
}
protected function get_other_values(renderer_base $output) {
$linkedcompetencycount = $this->data->competencycount - $this->data->unlinkedcompetencycount;
if ($linkedcompetencycount < 0) {
// Should never happen.
$linkedcompetencycount = 0;
}
$linkedcompetencypercentage = 0;
if ($this->data->competencycount > 0) {
$linkedcompetencypercentage = format_float(((float) $linkedcompetencycount /
(float) $this->data->competencycount) * 100.0);
}
$completedplanpercentage = 0;
if ($this->data->plancount > 0) {
$completedplanpercentage = format_float(((float) $this->data->completedplancount /
(float) $this->data->plancount) * 100.0);
}
$proficientusercompetencyplanpercentage = 0;
if ($this->data->usercompetencyplancount > 0) {
$proficientusercompetencyplanpercentage = format_float(((float) $this->data->proficientusercompetencyplancount /
(float) $this->data->usercompetencyplancount) * 100.0);
}
$competencies = array();
$contextcache = array();
foreach ($this->data->leastproficientcompetencies as $competency) {
if (!isset($contextcache[$competency->get_competencyframeworkid()])) {
$contextcache[$competency->get_competencyframeworkid()] = $competency->get_context();
}
$context = $contextcache[$competency->get_competencyframeworkid()];
$exporter = new competency_exporter($competency, array('context' => $context));
$competencies[] = $exporter->export($output);
}
return array(
'linkedcompetencycount' => $linkedcompetencycount,
'linkedcompetencypercentage' => $linkedcompetencypercentage,
'completedplanpercentage' => $completedplanpercentage,
'proficientusercompetencyplanpercentage' => $proficientusercompetencyplanpercentage,
'leastproficient' => $competencies,
'leastproficientcount' => count($competencies)
);
}
}
@@ -33,6 +33,8 @@ use context_system;
use moodle_url;
use tool_lp\api;
use tool_lp\external\competency_summary_exporter;
use tool_lp\template_statistics;
use tool_lp\external\template_statistics_exporter;
/**
* Class containing data for learning plan template competencies page
@@ -60,6 +62,9 @@ class template_competencies_page implements renderable, templatable {
/** @var context $pagecontext The page context. */
protected $pagecontext = null;
/** @var template_statistics $templatestatistics The generated summary statistics for this template. */
protected $templatestatistics = null;
/**
* Construct this renderable.
*
@@ -68,6 +73,7 @@ class template_competencies_page implements renderable, templatable {
public function __construct($templateid, context $pagecontext) {
$this->pagecontext = $pagecontext;
$this->templateid = $templateid;
$this->templatestatistics = new template_statistics($templateid);
$this->competencies = api::list_competencies_in_template($templateid);
$this->canmanagecompetencyframeworks = has_capability('tool/lp:competencymanage', $this->pagecontext);
$this->canmanagetemplatecompetencies = has_capability('tool/lp:templatemanage', $this->pagecontext);
@@ -115,6 +121,9 @@ class template_competencies_page implements renderable, templatable {
$data->canmanagecompetencyframeworks = $this->canmanagecompetencyframeworks;
$data->canmanagetemplatecompetencies = $this->canmanagetemplatecompetencies;
$data->manageurl = $this->manageurl->out(true);
$exporter = new template_statistics_exporter($this->templatestatistics);
$data->statistics = $exporter->export($output);
$data->showcompetencylinks = true;
return $data;
}
+32
View File
@@ -671,4 +671,36 @@ class plan extends persistent {
public static function has_records_for_template($templateid) {
return self::record_exists_select('templateid = ?', array($templateid));
}
/**
* Count the number of plans for a template, optionally filtering by status.
*
* @param int $templateid The template ID
* @param int $status The plan status. 0 means all statuses.
* @return int
*/
public static function count_records_for_template($templateid, $status) {
$filters = array('templateid' => $templateid);
if ($status > 0) {
$filters['status'] = $status;
}
return self::count_records($filters);
}
/**
* Get the plans for a template, optionally filtering by status.
*
* @param int $templateid The template ID
* @param int $status The plan status. 0 means all statuses.
* @param int $skip The number of plans to skip
* @param int $limit The max number of plans to return
* @return int
*/
public static function get_records_for_template($templateid, $status = 0, $skip = 0, $limit = 100) {
$filters = array('templateid' => $templateid);
if ($status > 0) {
$filters['status'] = $status;
}
return self::get_records($filters, $skip, $limit);
}
}
@@ -138,6 +138,29 @@ class template_competency extends persistent {
return $results;
}
/**
* Count the competencies in a template with no links to courses.
*
* @param int $templateid The template id
* @return int
*/
public static function count_competencies_with_no_courses($templateid) {
global $DB;
$sql = 'SELECT COUNT(comp.id)
FROM {' . self::TABLE . '} tplcomp
JOIN {' . competency::TABLE . '} comp
ON tplcomp.competencyid = comp.id
LEFT JOIN {' . course_competency::TABLE . '} crscomp
ON crscomp.competencyid = comp.id
WHERE tplcomp.templateid = ? AND crscomp.id IS NULL';
$params = array($templateid);
$results = $DB->count_records_sql($sql, $params);
return $results;
}
/**
* Get a single competency from the template (only if it is really in the template).
*
@@ -0,0 +1,76 @@
<?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/>.
/**
* Template statistics class
*
* @package tool_lp
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_lp;
defined('MOODLE_INTERNAL') || die();
/**
* Template statistics class.
*
* @package tool_lp
* @copyright 2016 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class template_statistics {
/** @var $competencycount The number of competencies in the template */
public $competencycount = 0;
/** @var $unlinkedcompetencycount The number of unlinked competencies in the template */
public $unlinkedcompetencycount = 0;
/** @var $plancount The number of plans for the template */
public $plancount = 0;
/** @var $completedplancount The number of completed plans for the template */
public $completedplancount = 0;
/** @var $usercompetencyplancount The number of competencies in completed plans for the template */
public $usercompetencyplancount = 0;
/** @var $proficientusercompetencyplancount The number of proficient competencies in completed plans for the template */
public $proficientusercompetencyplancount = 0;
/** @var $leastproficientcompetencies The competencies in this template that were proficient the least times */
public $leastproficientcompetencies = array();
/**
* Return the custom definition of the properties of this model.
*
* @param int $template The template we want to generate statistics for.
*/
public function __construct($templateid) {
$template = new template($templateid);
$this->competencycount = api::count_competencies_in_template($template);
$this->unlinkedcompetencycount = api::count_competencies_in_template_with_no_courses($template);
$this->plancount = api::count_plans_for_template($template, 0);
$this->completedplancount = api::count_plans_for_template($template, plan::STATUS_COMPLETE);
$this->usercompetencyplancount = api::count_user_competency_plans_for_template($template, false);
$this->proficientusercompetencyplancount = api::count_user_competency_plans_for_template($template, true);
$this->leastproficientcompetencies = api::get_least_proficient_competencies_for_template($template, 0, 3);
}
}
@@ -280,4 +280,64 @@ class user_competency_plan extends persistent {
return self::record_exists_select("competencyid $insql", $params);
}
/**
* Count the number of records matching a specific template, optionally filtered by proficient values.
*
* @param int $templateid
* @param mixed $proficiency - If true - filter by proficiency, if false filter by not proficient, if null - do not filter.
* @return int
*/
public static function count_records_for_template($templateid, $proficiency=null) {
global $DB;
$params = array('templateid' => $templateid);
$sql = 'SELECT ' . " COUNT('x') " .
'FROM {' . self::TABLE . '} ucp
JOIN {' . plan::TABLE . '} p
ON ucp.planid = p.id
WHERE p.templateid = :templateid';
if ($proficiency === true) {
$sql .= ' AND ucp.proficiency = :proficiency';
$params['proficiency'] = true;
} else if ($proficiency === false) {
$sql .= ' AND (ucp.proficiency = :proficiency OR ucp.proficiency IS NULL)';
$params['proficiency'] = false;
}
return $DB->count_records_sql($sql, $params);
}
/**
* Get the list of competencies that were completed the least times (in completed plans) from a template.
*
* @param int $templateid
* @param int $skip The number of competencies to skip
* @param int $limit The max number of competencies to return
* @return competency[]
*/
public static function get_least_proficient_competencies_for_template($templateid, $skip = 0, $limit = 0) {
global $DB;
$fields = competency::get_sql_fields('c');
$params = array('templateid' => $templateid, 'notproficient' => false);
$sql = 'SELECT ' . $fields . ', COUNT(c.id) AS timesnotproficient ' .
' FROM {' . self::TABLE . '} ucp
JOIN {' . plan::TABLE . '} p
ON ucp.planid = p.id
JOIN {' . competency::TABLE . '} c
ON ucp.competencyid = c.id
WHERE p.templateid = :templateid
AND (ucp.proficiency = :notproficient OR ucp.proficiency IS NULL)
GROUP BY c.id
ORDER BY timesnotproficient DESC';
$results = $DB->get_records_sql($sql, $params, $skip, $limit);
$comps = array();
foreach ($results as $r) {
$c = competency::extract_record($r);
$comps[] = new competency(0, $c);
}
return $comps;
}
}
+4
View File
@@ -38,6 +38,7 @@ $string['allchildrenarecomplete'] = 'All children are complete';
$string['aplanswerecreated'] = '{$a} plans were created.';
$string['aplanswerecreatedmoremayrequiresync'] = '{$a} plans were created, more will be created during the next synchronization.';
$string['assigncohorts'] = 'Assign cohorts';
$string['averageproficiencyrate'] = 'The average proficiency rate for completed plans based on this template is {$a} %';
$string['cancelreviewrequest'] = 'Cancel review request';
$string['cannotaddrules'] = 'This competency cannot be configured.';
$string['cannotcreateuserplanswhentemplateduedateispassed'] = 'New user plans can not be created: this template\'s due date has, or is about to, expire.';
@@ -47,6 +48,7 @@ $string['cohortssyncedtotemplate'] = 'Cohorts synced to this template';
$string['competencies'] = 'Competencies';
$string['competenciesarenotenabled'] = 'The competencies module is not enabled.';
$string['competenciesforframework'] = 'Competencies for {$a}';
$string['competenciesmostoftennotproficient'] = 'Competencies most often not proficient in completed plans';
$string['competenciessettings'] = 'Competencies settings';
$string['competencycannotbedeleted'] = 'The competency \'{$a}\' can not be deleted';
$string['competencycreated'] = 'Competency created';
@@ -418,3 +420,5 @@ $string['viewdetails'] = 'View details';
$string['visible'] = 'Visible';
$string['visible_help'] = 'A competency framework can be hidden from teachers. This could be useful if a framework is still in the process of being developed.';
$string['when'] = 'When';
$string['xcompetencieslinkedoutofy'] = '{$a->x} out of {$a->y} competencies linked to courses';
$string['xplanscompletedoutofy'] = '{$a->x} out of {$a->y} plans completed for this template';
+11 -1
View File
@@ -4,7 +4,17 @@
.path-admin-tool-lp [data-region="competencylinktree"] ul li {
list-style-type: none;
}
.path-admin-tool-lp [data-region="templatestatistics"] .progresstext {
display: inline-block;
height: 40px;
vertical-align: top;
}
.path-admin-tool-lp [data-region="templatestatistics"] .progress {
width: 10em;
display: inline-block;
margin-left: 2em;
margin-right: 2em;
}
.path-admin-tool-lp [data-region="managecompetencies"] ul[data-enhance="tree"],
.path-admin-tool-lp [data-region="plans"] ul[data-enhance="tree"],
.path-admin-tool-lp [data-region="competencylinktree"] ul[data-enhance="linktree"],
@@ -18,6 +18,21 @@
Template competencies template.
}}
<div data-region="templatecompetenciespage">
{{#statistics}}
{{> tool_lp/template_statistics }}
{{/statistics}}
<div data-region="actions">
{{#canmanagecompetencyframeworks}}
<div class="pull-right">
<p><a href="{{manageurl}}">{{#str}}managecompetenciesandframeworks, tool_lp{{/str}}</a></p>
</div>
{{/canmanagecompetencyframeworks}}
{{#canmanagetemplatecompetencies}}
<p>
<button style="display: none">{{#str}}linktemplatecompetencies, tool_lp{{/str}}</button>
</p>
{{/canmanagetemplatecompetencies}}
</div>
<div data-region="templatecompetencies">
<div class="managecompetencies">
<div class="drag-parentnode">
@@ -31,6 +46,7 @@
</div>
{{/canmanagetemplatecompetencies}}
{{#competency}}
<a id="competency-info-link-{{competency.idnumber}}"></a>
{{> tool_lp/competency_summary }}
{{/competency}}
<strong>{{#str}}linkedcourseslist, tool_lp{{/str}}</strong>
@@ -55,16 +71,6 @@
</p>
{{/competencies}}
</div>
<div data-region="actions">
<div class="pull-right">
{{#canmanagetemplatecompetencies}}
<button style="display: none">{{#str}}linktemplatecompetencies, tool_lp{{/str}}</button>
{{/canmanagetemplatecompetencies}}
</div>
{{#canmanagecompetencyframeworks}}
<p><a href="{{manageurl}}">{{#str}}managecompetenciesandframeworks, tool_lp{{/str}}</a></p>
{{/canmanagecompetencyframeworks}}
</div>
</div>
{{#js}}
require(['tool_lp/competencies'], function(mod) {
@@ -0,0 +1,102 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template tool_lp/template_statistics
IDs required for JS:
* none
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
See admin/tool/lp/classes/external/template_statistics_exporter
Example context (json):
{
linkedcompetencycount: 4,
competencycount: 8,
linkedcompetencypercentage: 50,
plancount: 40,
completedplancount: 30,
completedplanpercentage: 75,
}
}}
{{!
Template statistics template.
}}
{{#competencycount}}
<div data-region="templatestatistics" class="well">
<div>
<div class="progresstext">
{{#str}}xcompetencieslinkedoutofy, tool_lp, { "x": "{{linkedcompetencycount}}", "y": "{{competencycount}}" } {{/str}}
</div>
<div class="progress">
<div class="bar" style="width: {{linkedcompetencypercentage}}%;">
{{linkedcompetencypercentage}} %
</div>
</div>
</div>
{{#plancount}}
<div>
<div class="progresstext">
{{#str}}xplanscompletedoutofy, tool_lp, { "x": "{{completedplancount}}", "y": "{{plancount}}" } {{/str}}
</div>
<div class="progress">
<div class="bar" style="width: {{completedplanpercentage}}%;">
{{completedplanpercentage}} %
</div>
</div>
</div>
{{/plancount}}
{{#usercompetencyplancount}}
<div>
<div class="progresstext">
{{#str}}averageproficiencyrate, tool_lp, {{proficientusercompetencyplanpercentage}} {{/str}}
</div>
<div class="progress">
<div class="bar" style="width: {{proficientusercompetencyplanpercentage}}%;">
{{proficientusercompetencyplanpercentage}} %
</div>
</div>
</div>
{{/usercompetencyplancount}}
{{#leastproficientcount}}
<div>
<div>
<p>{{#str}}competenciesmostoftennotproficient, tool_lp{{/str}}</p>
</div>
<div>
{{#leastproficient}}
{{#showcompetencylinks}}
<a href="#competency-info-link-{{idnumber}}">
{{/showcompetencylinks}}
<div><p>{{shortname}} <em>{{idnumber}}</em></p></div>
{{#showcompetencylinks}}
</a>
{{/showcompetencylinks}}
{{/leastproficient}}
</div>
</div>
{{/leastproficientcount}}
</div>
{{/competencycount}}
+140
View File
@@ -4028,4 +4028,144 @@ class tool_lp_api_testcase extends advanced_testcase {
$this->assertEquals(null, $uc2->get_grade());
$this->assertEquals(null, $uc2->get_proficiency());
}
/**
* Test template statistics api functions.
*/
public function test_template_statistics() {
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('tool_lp');
$this->setAdminUser();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$c1 = $dg->create_course();
$framework = $lpg->create_framework();
// Create 6 competencies.
$comp1 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
$comp2 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
$comp3 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
$comp4 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
$comp5 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
$comp6 = $lpg->create_competency(array('competencyframeworkid' => $framework->get_id()));
// Link 5 out of 6 to a course.
$lpg->create_course_competency(array('competencyid' => $comp1->get_id(), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp2->get_id(), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp3->get_id(), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp4->get_id(), 'courseid' => $c1->id));
$lpg->create_course_competency(array('competencyid' => $comp5->get_id(), 'courseid' => $c1->id));
// Put all 6 in a template.
$tpl = $this->getDataGenerator()->get_plugin_generator('tool_lp')->create_template();
$tplc1 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp1->get_id()));
$tplc2 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp2->get_id()));
$tplc3 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp3->get_id()));
$tplc4 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp4->get_id()));
$tplc5 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp5->get_id()));
$tplc6 = $lpg->create_template_competency(array('templateid' => $tpl->get_id(), 'competencyid' => $comp6->get_id()));
// Create some plans from the template.
$p1 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u1->id));
$p2 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u2->id));
$p3 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u3->id));
$p4 = $lpg->create_plan(array('templateid' => $tpl->get_id(), 'userid' => $u4->id));
// Rate some competencies.
// User 1.
$lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp1->get_id(),
'proficiency' => true, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp2->get_id(),
'proficiency' => true, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u1->id, 'competencyid' => $comp3->get_id(),
'proficiency' => true, 'grade' => 1 ));
// User 2.
$lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp1->get_id(),
'proficiency' => false, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp2->get_id(),
'proficiency' => false, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u2->id, 'competencyid' => $comp3->get_id(),
'proficiency' => false, 'grade' => 1 ));
// User 3.
$lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp2->get_id(),
'proficiency' => false, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp3->get_id(),
'proficiency' => true, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp4->get_id(),
'proficiency' => false, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u3->id, 'competencyid' => $comp5->get_id(),
'proficiency' => true, 'grade' => 1 ));
// User 4.
$lpg->create_user_competency(array('userid' => $u4->id, 'competencyid' => $comp3->get_id(),
'proficiency' => true, 'grade' => 1 ));
$lpg->create_user_competency(array('userid' => $u4->id, 'competencyid' => $comp5->get_id(),
'proficiency' => true, 'grade' => 1 ));
// Complete 3 out of 4 plans.
api::complete_plan($p1->get_id());
api::complete_plan($p2->get_id());
api::complete_plan($p3->get_id());
// OK we have enough data - lets call some API functions and check for expected results.
$result = api::count_competencies_in_template_with_no_courses($tpl->get_id());
$this->assertEquals(1, $result);
$result = api::count_plans_for_template($tpl->get_id());
$this->assertEquals(4, $result);
$result = api::count_plans_for_template($tpl->get_id(), plan::STATUS_COMPLETE);
$this->assertEquals(3, $result);
// This counts the records of competencies in completed plans for all users with a plan from this template.
$result = api::count_user_competency_plans_for_template($tpl->get_id());
// There should be 3 plans * 6 competencies.
$this->assertEquals(18, $result);
// This counts the records of proficient competencies in completed plans for all users with a plan from this template.
$result = api::count_user_competency_plans_for_template($tpl->get_id(), true);
// There should be 5.
$this->assertEquals(5, $result);
// This counts the records of not proficient competencies in completed plans for all users with a plan from this template.
$result = api::count_user_competency_plans_for_template($tpl->get_id(), false);
// There should be 13.
$this->assertEquals(13, $result);
// This lists the plans based on this template, optionally filtered by status.
$result = api::list_plans_for_template($tpl->get_id());
$this->assertEquals(4, count($result));
foreach ($result as $one) {
$this->assertInstanceOf('\tool_lp\plan', $one);
}
// This lists the plans based on this template, optionally filtered by status.
$result = api::list_plans_for_template($tpl->get_id(), plan::STATUS_COMPLETE);
$this->assertEquals(3, count($result));
foreach ($result as $one) {
$this->assertInstanceOf('\tool_lp\plan', $one);
$this->assertEquals(plan::STATUS_COMPLETE, $one->get_status());
}
$result = api::get_least_proficient_competencies_for_template($tpl->get_id(), 0, 2);
// Our times completed counts should look like this:
// comp1 - 1
// comp2 - 1
// comp3 - 2
// comp4 - 0
// comp5 - 1
// comp6 - 0
$this->assertEquals(2, count($result));
$leastarray = array($comp4->get_id(), $comp6->get_id());
foreach ($result as $one) {
$this->assertInstanceOf('\tool_lp\competency', $one);
$this->assertContains($one->get_id(), $leastarray);
}
}
}