MDL-51034 tool_lp: List competencies in a user's plan
This commit is contained in:
@@ -1306,6 +1306,52 @@ class api {
|
||||
return $plan->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* List the competencies in a user plan.
|
||||
*
|
||||
* @param int $planorid The plan, or its ID.
|
||||
* @return array((object) array('competency' => competency, 'usercompetency' => user_competency))
|
||||
*/
|
||||
public static function list_plan_competencies($planorid) {
|
||||
$plan = $planorid;
|
||||
if (!is_object($planorid)) {
|
||||
$plan = new plan($planorid);
|
||||
}
|
||||
|
||||
if (!$plan->can_read()) {
|
||||
$context = context_user::instance($plan->get_userid());
|
||||
throw new required_capability_exception($context, 'tool/lp:planview', 'nopermissions', '');
|
||||
}
|
||||
|
||||
$result = array();
|
||||
$competencies = $plan->get_competencies();
|
||||
$usercompetencies = user_competency::get_multiple($plan->get_userid(), $competencies);
|
||||
|
||||
// Build the return values.
|
||||
foreach ($competencies as $key => $competency) {
|
||||
$found = false;
|
||||
|
||||
foreach ($usercompetencies as $uckey => $uc) {
|
||||
if ($uc->get_competencyid() == $competency->get_id()) {
|
||||
$found = true;
|
||||
unset($usercompetencies[$uckey]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$uc = user_competency::create_relation($plan->get_userid(), $competency->get_id());
|
||||
}
|
||||
|
||||
$result[] = (object) array(
|
||||
'competency' => $competency,
|
||||
'usercompetency' => $uc,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the related competencies.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,8 @@ use context;
|
||||
use lang_string;
|
||||
use stdClass;
|
||||
|
||||
require_once($CFG->libdir . '/grade/grade_scale.php');
|
||||
|
||||
/**
|
||||
* Class for loading/storing competency frameworks from the DB.
|
||||
*
|
||||
@@ -111,6 +113,17 @@ class competency_framework extends persistent {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale.
|
||||
*
|
||||
* @return \grade_scale
|
||||
*/
|
||||
public function get_scale() {
|
||||
$scale = \grade_scale::fetch(array('id' => $this->get_scaleid()));
|
||||
$scale->load_items();
|
||||
return $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the constant name for a level.
|
||||
*
|
||||
|
||||
@@ -865,6 +865,69 @@ class external extends external_api {
|
||||
return new external_single_structure($returns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the external structure of a full user_competency record.
|
||||
*
|
||||
* @return \external_single_structure
|
||||
*/
|
||||
protected static function get_user_competency_external_structure() {
|
||||
$id = new external_value(
|
||||
PARAM_INT,
|
||||
'Database record id'
|
||||
);
|
||||
$userid = new external_value(
|
||||
PARAM_INT,
|
||||
'User to whom this record belongs to'
|
||||
);
|
||||
$competencyid = new external_value(
|
||||
PARAM_INT,
|
||||
'The competency associated with this record'
|
||||
);
|
||||
$status = new external_value(
|
||||
PARAM_INT,
|
||||
'The status of the user competency'
|
||||
);
|
||||
$reviewerid = new external_value(
|
||||
PARAM_INT,
|
||||
'The reviewer ID'
|
||||
);
|
||||
$proficiency = new external_value(
|
||||
PARAM_BOOL,
|
||||
'Whether or not the user is proficient'
|
||||
);
|
||||
$grade = new external_value(
|
||||
PARAM_INT,
|
||||
'The scale grade'
|
||||
);
|
||||
$timecreated = new external_value(
|
||||
PARAM_INT,
|
||||
'Timestamp this record was created'
|
||||
);
|
||||
$timemodified = new external_value(
|
||||
PARAM_INT,
|
||||
'Timestamp this record was modified'
|
||||
);
|
||||
$usermodified = new external_value(
|
||||
PARAM_INT,
|
||||
'User who modified this record last'
|
||||
);
|
||||
|
||||
$returns = array(
|
||||
'id' => $id,
|
||||
'userid' => $userid,
|
||||
'competencyid' => $competencyid,
|
||||
'status' => $status,
|
||||
'reviewerid' => $reviewerid,
|
||||
'proficiency' => $proficiency,
|
||||
'grade' => $grade,
|
||||
'timecreated' => $timecreated,
|
||||
'timemodified' => $timemodified,
|
||||
'usermodified' => $usermodified,
|
||||
);
|
||||
|
||||
return new external_single_structure($returns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of create_competency() parameters.
|
||||
*
|
||||
@@ -3356,6 +3419,50 @@ class external extends external_api {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* External function parameters structure.
|
||||
*
|
||||
* @return \external_description
|
||||
*/
|
||||
public static function list_plan_competencies_parameters() {
|
||||
return new external_single_structure(array(
|
||||
'id' => new external_value(PARAM_INT, 'The plan ID.')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* List plan competencies.
|
||||
* @param int $id The plan ID.
|
||||
* @return array
|
||||
*/
|
||||
public static function list_plan_competencies($id) {
|
||||
$params = self::validate_parameters(self::list_plan_competencies_parameters(), array('id' => $id));
|
||||
$id = $params['id'];
|
||||
$plan = api::read_plan($id);
|
||||
$result = api::list_plan_competencies($plan);
|
||||
foreach ($result as $key => $r) {
|
||||
$r->competency = $r->competency->to_record();
|
||||
$r->competency->descriptionformatted = format_text($r->competency->description,
|
||||
$r->competency->descriptionformat, array('context' => $plan->get_context()));
|
||||
$r->usercompetency = $r->usercompetency->to_record();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* External function return structure.
|
||||
*
|
||||
* @return \external_description
|
||||
*/
|
||||
public static function list_plan_competencies_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_single_structure(array(
|
||||
'competency' => self::get_competency_external_structure(),
|
||||
'usercompetency' => self::get_user_competency_external_structure(),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the get_scale_values() parameters.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Plan page output.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_lp\output;
|
||||
|
||||
use renderable;
|
||||
use templatable;
|
||||
use stdClass;
|
||||
use tool_lp\api;
|
||||
use tool_lp\user_competency;
|
||||
use context_user;
|
||||
|
||||
/**
|
||||
* Plan page class.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class plan_page implements renderable, templatable {
|
||||
|
||||
/** @var plan */
|
||||
protected $plan;
|
||||
|
||||
/**
|
||||
* Construct.
|
||||
*
|
||||
* @param plan $plan
|
||||
*/
|
||||
public function __construct($plan) {
|
||||
$this->plan = $plan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the data.
|
||||
*
|
||||
* @param renderer_base $output
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output) {
|
||||
$options = array('context' => $this->plan->get_context());
|
||||
$frameworks = array();
|
||||
$scales = array();
|
||||
|
||||
$data = new stdClass();
|
||||
$data->competencies = array();
|
||||
|
||||
$pclist = api::list_plan_competencies($this->plan);
|
||||
foreach ($pclist as $pc) {
|
||||
$comp = $pc->competency;
|
||||
$usercomp = $pc->usercompetency;
|
||||
|
||||
if (!isset($frameworks[$comp->get_competencyframeworkid()])) {
|
||||
$frameworks[$comp->get_competencyframeworkid()] = $comp->get_framework();
|
||||
}
|
||||
$framework = $frameworks[$comp->get_competencyframeworkid()];
|
||||
if (!isset($scales[$framework->get_scaleid()])) {
|
||||
$scales[$framework->get_scaleid()] = $framework->get_scale();
|
||||
}
|
||||
$scale = $scales[$framework->get_scaleid()];
|
||||
|
||||
// Prepare the data.
|
||||
$competency = $comp->to_record();
|
||||
$competency->descriptionformatted = format_text($competency->description, $competency->descriptionformat, $options);
|
||||
$usercompetency = $usercomp->to_record();
|
||||
$competency->usercompetency = $usercompetency;
|
||||
|
||||
if ($usercompetency->grade === null) {
|
||||
$gradename = '-';
|
||||
} else {
|
||||
$gradename = format_string($scale->scale_items[$usercompetency->grade - 1], null, $options);
|
||||
}
|
||||
|
||||
if ($usercompetency->proficiency === null) {
|
||||
$proficiencyname = '-';
|
||||
} else {
|
||||
$proficiencyname = get_string($usercompetency->proficiency ? 'yes' : 'no');
|
||||
}
|
||||
|
||||
$statusname = '-';
|
||||
if ($usercompetency->status != user_competency::STATUS_IDLE) {
|
||||
$statusname = (string) user_competency::get_status_name($usercompetency->status);
|
||||
}
|
||||
|
||||
$usercompetency->gradename = $gradename;
|
||||
$usercompetency->proficiencyname = $proficiencyname;
|
||||
$usercompetency->statusname = $statusname;
|
||||
|
||||
$data->competencies[] = $competency;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,17 @@ class renderer extends plugin_renderer_base {
|
||||
return parent::render_from_template('tool_lp/manage_templates_page', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer to template.
|
||||
*
|
||||
* @param plan_page $page
|
||||
* @return bool|string
|
||||
*/
|
||||
public function render_plan_page(plan_page $page) {
|
||||
$data = $page->export_for_template($this);
|
||||
return parent::render_from_template('tool_lp/plan_page', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer to template.
|
||||
*
|
||||
|
||||
@@ -629,7 +629,7 @@ abstract class persistent {
|
||||
* @param int $skip Limitstart.
|
||||
* @param int $limit Number of rows to return.
|
||||
*
|
||||
* @return persistent[]
|
||||
* @return \tool_lp\persistent[]
|
||||
*/
|
||||
public static function get_records($filters = array(), $sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
|
||||
global $DB;
|
||||
@@ -658,7 +658,7 @@ abstract class persistent {
|
||||
* @param string $fields
|
||||
* @param int $limitfrom
|
||||
* @param int $limitnum
|
||||
* @return \tool_lp\plan[]
|
||||
* @return \tool_lp\persistent[]
|
||||
*/
|
||||
public static function get_records_select($select, $params = null, $sort = '', $fields = '*', $limitfrom = 0, $limitnum = 0) {
|
||||
global $DB;
|
||||
|
||||
@@ -109,6 +109,33 @@ class plan extends persistent {
|
||||
return self::can_read_user($this->get_userid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the competencies in this plan.
|
||||
*
|
||||
* @return competency[]
|
||||
*/
|
||||
public function get_competencies() {
|
||||
$competencies = array();
|
||||
if ($this->get_templateid()) {
|
||||
// Get the competencies from the template.
|
||||
$competencies = template_competency::list_competencies($this->get_templateid(), true);
|
||||
} else {
|
||||
// TODO MDL-50328.
|
||||
// Get the competencies in this plan.
|
||||
// $competencies = plan_competency::list_competencies($this->get_id());
|
||||
}
|
||||
return $competencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context in which the plan is attached.
|
||||
*
|
||||
* @return context_user
|
||||
*/
|
||||
public function get_context() {
|
||||
return context_user::instance($this->get_userid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Human readable status name.
|
||||
*
|
||||
|
||||
@@ -157,8 +157,7 @@ class template_competency extends persistent {
|
||||
FROM {' . competency::TABLE . '} comp
|
||||
JOIN {' . self::TABLE . '} tplcomp
|
||||
ON tplcomp.competencyid = comp.id
|
||||
WHERE tplcomp.templateid = ?
|
||||
ORDER BY tplcomp.sortorder ASC';
|
||||
WHERE tplcomp.templateid = ?';
|
||||
$params = array($templateid);
|
||||
|
||||
if ($onlyvisible) {
|
||||
@@ -166,6 +165,8 @@ class template_competency extends persistent {
|
||||
$params[] = 1;
|
||||
}
|
||||
|
||||
$sql .= 'ORDER BY tplcomp.sortorder ASC';
|
||||
|
||||
$results = $DB->get_records_sql($sql, $params);
|
||||
|
||||
$instances = array();
|
||||
|
||||
@@ -190,4 +190,52 @@ class user_competency extends persistent {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user_competency object.
|
||||
*
|
||||
* Note, this is intended to be used to create a blank relation, for instance when
|
||||
* the record was not found in the database. This does not save the model.
|
||||
*
|
||||
* @param int $userid The user ID.
|
||||
* @param int $competencyid The competency ID.
|
||||
* @return \tool_lp\user_competency
|
||||
*/
|
||||
public static function create_relation($userid, $competencyid) {
|
||||
$relation = new user_competency(0, (object) array('userid' => $userid, 'competencyid' => $competencyid));
|
||||
return $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple user_competency for a user.
|
||||
*
|
||||
* @param int $userid
|
||||
* @param array $competenciesorids Limit search to those competencies, or competency IDs.
|
||||
* @return \tool_lp\user_competency[]
|
||||
*/
|
||||
public static function get_multiple($userid, array $competenciesorids = null) {
|
||||
global $DB;
|
||||
|
||||
$params = array();
|
||||
$params['userid'] = $userid;
|
||||
$sql = '1 = 1';
|
||||
|
||||
if (!empty($competenciesorids)) {
|
||||
$test = reset($competenciesorids);
|
||||
if (is_int($test)) {
|
||||
$ids = $competenciesorids;
|
||||
} else {
|
||||
$ids = array();
|
||||
foreach ($competenciesorids as $comp) {
|
||||
$ids[] = $comp->get_id();
|
||||
}
|
||||
}
|
||||
|
||||
list($insql, $inparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED);
|
||||
$params += $inparams;
|
||||
$sql = "competencyid $insql";
|
||||
}
|
||||
|
||||
return parent::get_records_select("userid = :userid AND $sql", $params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -424,6 +424,15 @@ $functions = array(
|
||||
'capabilities' => 'tool/lp:planviewown',
|
||||
'ajax' => true,
|
||||
),
|
||||
'tool_lp_list_plan_competencies' => array(
|
||||
'classname' => 'tool_lp\external',
|
||||
'methodname' => 'list_plan_competencies',
|
||||
'classpath' => '',
|
||||
'description' => 'List the competencies in a plan',
|
||||
'type' => 'read',
|
||||
'capabilities' => 'tool/lp:planviewown',
|
||||
'ajax' => true,
|
||||
),
|
||||
'tool_lp_get_scale_values' => array(
|
||||
'classname' => 'tool_lp\external',
|
||||
'methodname' => 'get_scale_values',
|
||||
|
||||
@@ -39,9 +39,6 @@ $string['competencyframeworks'] = 'Competency Frameworks';
|
||||
$string['competencyframeworkupdated'] = 'Competency framework updated.';
|
||||
$string['competencypicker'] = 'Competency picker';
|
||||
$string['competencyrelatedcompetencies'] = '{$a} related competencies';
|
||||
$string['usercompetencystatus_idle'] = 'Idle';
|
||||
$string['usercompetencystatus_inreview'] = 'In review';
|
||||
$string['usercompetencystatus_waitingforreview'] = 'Waiting for review';
|
||||
$string['competencyupdated'] = 'Competency updated';
|
||||
$string['configurescale'] = 'Configure scales';
|
||||
$string['coursecompetencies'] = 'Course competencies';
|
||||
@@ -134,6 +131,7 @@ $string['search'] = 'Search...';
|
||||
$string['selectcompetencymovetarget'] = 'Select a location to move this competency to:';
|
||||
$string['selectedcompetency'] = 'Selected competency';
|
||||
$string['shortname'] = 'Name';
|
||||
$string['state'] = 'State';
|
||||
$string['status'] = 'Status';
|
||||
$string['taxonomies'] = 'Taxonomies';
|
||||
$string['taxonomy_add_behaviour'] = 'Add behaviour';
|
||||
@@ -196,5 +194,8 @@ $string['templatecreated'] = 'Learning plan template created';
|
||||
$string['templatename'] = 'Name';
|
||||
$string['templates'] = 'Learning plan templates';
|
||||
$string['templateupdated'] = 'Learning plan template updated';
|
||||
$string['usercompetencystatus_idle'] = 'Idle';
|
||||
$string['usercompetencystatus_inreview'] = 'In review';
|
||||
$string['usercompetencystatus_waitingforreview'] = 'Waiting for review';
|
||||
$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.';
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Plan page.
|
||||
*
|
||||
* @package tool_lp
|
||||
* @copyright 2015 Frédéric Massart - FMCorz.net
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require(__DIR__ . '/../../../config.php');
|
||||
|
||||
$id = required_param('id', PARAM_INT);
|
||||
|
||||
require_login(null, false);
|
||||
if (isguestuser()) {
|
||||
throw new require_login_exception('Guests are not allowed here.');
|
||||
}
|
||||
|
||||
$plan = \tool_lp\api::read_plan($id);
|
||||
$context = $plan->get_context();
|
||||
|
||||
$url = new moodle_url('/admin/tool/lp/plan.php', array('id' => $id));
|
||||
$title = format_string($plan->get_name(), true, array('context' => $context));
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->set_pagelayout('admin');
|
||||
$PAGE->set_url($url);
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($title);
|
||||
|
||||
$output = $PAGE->get_renderer('tool_lp');
|
||||
echo $output->header();
|
||||
echo $output->heading($title);
|
||||
|
||||
$page = new \tool_lp\output\plan_page($plan);
|
||||
echo $output->render($page);
|
||||
|
||||
echo $output->footer();
|
||||
@@ -0,0 +1,53 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
Plan page template.
|
||||
}}
|
||||
<div data-region="planpage">
|
||||
|
||||
<table class="generaltable fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{#str}}shortname, tool_lp{{/str}}</th>
|
||||
<th scope="col">{{#str}}status, tool_lp{{/str}}</th>
|
||||
<th scope="col">{{#str}}proficient, tool_lp{{/str}}</th>
|
||||
<th scope="col">{{#str}}state, tool_lp{{/str}}</th>
|
||||
<th scope="col">{{#str}}actions, tool_lp{{/str}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#competencies}}
|
||||
<tr data-id="{{id}}">
|
||||
<td>{{shortname}}</td>
|
||||
<td>{{usercompetency.gradename}}</td>
|
||||
<td>{{usercompetency.proficiencyname}}</td>
|
||||
<td>{{usercompetency.statusname}}</td>
|
||||
<td><!-- Option to remove the competency from the plan, ... --></td>
|
||||
</tr>
|
||||
{{/competencies}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div data-region="actions">
|
||||
<div class="pull-right">
|
||||
<!-- Button to add competencies to the plan -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{#js}}
|
||||
{{/js}}
|
||||
Reference in New Issue
Block a user