MDL-51042 tool_lp: Add useful statistics to the template competencies page.
This commit is contained in:
committed by
Frederic Massart
parent
b986597039
commit
3edcd295eb
+130
-11
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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}}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user