473 lines
13 KiB
PHP
473 lines
13 KiB
PHP
<?php
|
|
require_once($CFG->libdir.'/gradelib.php');
|
|
require_once($CFG->libdir.'/externallib.php');
|
|
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
|
|
//namespace block_gradelevel;
|
|
|
|
|
|
class block_gradelevel_skillmgmtservice extends external_api
|
|
{
|
|
const DEBUG = false; // enable debug logging
|
|
const DEMOBADGE_SIZE = 150; // size of demo badge
|
|
|
|
private static function log($message)
|
|
{
|
|
if(self::DEBUG)
|
|
{
|
|
error_log($message."\n",3,"/tmp/block_gradelevel.log");
|
|
}
|
|
}
|
|
|
|
private static function list_courses($skill_id)
|
|
{
|
|
global $DB;
|
|
$list = array();
|
|
$links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $skill_id));
|
|
foreach($links as $link)
|
|
{
|
|
$list[] = $link->course_id;
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
// Input parameter config
|
|
public static function submit_levels_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'skill_id' => new external_value(PARAM_INT, 'id of skill'),
|
|
'levels' => new external_multiple_structure(
|
|
new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function list_levels_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'skill_id' => new external_value(PARAM_INT, 'id of skill'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function list_skills_parameters()
|
|
{
|
|
return new external_function_parameters( array() );
|
|
}
|
|
|
|
public static function get_skill_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'id of skill'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function update_skill_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'id of skill'),
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function add_skill_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function delete_skill_parameters()
|
|
{
|
|
return new external_function_parameters(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
)
|
|
);
|
|
}
|
|
|
|
// Output parameter config
|
|
public static function submit_levels_returns()
|
|
{
|
|
return new external_multiple_structure(
|
|
new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function list_levels_returns()
|
|
{
|
|
return new external_multiple_structure(
|
|
new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function list_skills_returns()
|
|
{
|
|
return new external_multiple_structure(
|
|
new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function get_skill_returns()
|
|
{
|
|
return new external_single_structure(
|
|
array(
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function update_skill_returns()
|
|
{
|
|
return new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function add_skill_returns()
|
|
{
|
|
return new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function delete_skill_returns()
|
|
{
|
|
return new external_single_structure(
|
|
array(
|
|
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
'deleted' => new external_value(PARAM_BOOL, 'Deletion succesful'),
|
|
)
|
|
);
|
|
}
|
|
|
|
// Actual functions
|
|
public static function submit_levels(int $skill_id, array $levels)
|
|
{
|
|
global $CFG, $DB;
|
|
self::log("submit_levels called, skill_id: {$skill_id}, levels: \n".print_r($levels,true));
|
|
|
|
$systemcontext = context_system::instance();
|
|
self::validate_context($systemcontext);
|
|
|
|
|
|
foreach($levels as $lvl_raw)
|
|
{
|
|
// convert level array to stdObj
|
|
$lvl = (object) $lvl_raw;
|
|
$lvl->levelset_id = $skill_id;
|
|
|
|
self::log("Processing level: ".print_r($lvl,true));
|
|
|
|
if($lvl->points >= 0)
|
|
{
|
|
if($lvl->id >= 0)
|
|
{
|
|
// Update record
|
|
self::log("updating row {$lvl->id}: {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}");
|
|
$DB->update_record('block_gradelevel_levels',$lvl);
|
|
}
|
|
else
|
|
{
|
|
// unset invalid id before insert
|
|
unset($lvl->id);
|
|
self::log("inserting new row {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}");
|
|
// Insert record
|
|
$DB->insert_record('block_gradelevel_levels',$lvl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// points is empty: delete record if we have a valid id.
|
|
if($lvl->id >= 0)
|
|
{
|
|
self::log("deleting empty row {$lvl->id}");
|
|
$DB->delete_records('block_gradelevel_levels', array('id' => $lvl->id));
|
|
}
|
|
else
|
|
{
|
|
self::log("ignoring empty row");
|
|
}
|
|
|
|
}/**/
|
|
|
|
}
|
|
|
|
return static::list_levels($skill_id);
|
|
}
|
|
|
|
public static function list_levels(int $skill_id)
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $skill_id));
|
|
|
|
if($skill_id == 0 || count($levels) > 0)
|
|
{
|
|
// If global level, or skills are defined, return those
|
|
|
|
// Sort by points
|
|
usort( $levels, function( $a, $b) {
|
|
return ( $a->points < $b->points ) ? -1 : 1;
|
|
} );
|
|
|
|
|
|
return $levels;
|
|
}
|
|
else
|
|
{
|
|
// Else, return a nameless clone of the default levels).
|
|
$levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
|
|
|
|
// Sort by points
|
|
usort( $levels, function( $a, $b) {
|
|
return ( $a->points < $b->points ) ? -1 : 1;
|
|
} );
|
|
|
|
foreach($levels as $lvl)
|
|
{
|
|
$lvl->id = -255; // replace level id with -255, which is code for "new level" when returned
|
|
}
|
|
|
|
return $levels;
|
|
}
|
|
|
|
}
|
|
|
|
public static function list_skills()
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$skills = $DB->get_records('block_gradelevel_levelset');
|
|
|
|
// Sort by points
|
|
usort( $skills, function( $a, $b) {
|
|
return ( $a->name < $b->name) ? -1 : 1;
|
|
} );
|
|
|
|
foreach($skills as $skill )
|
|
{
|
|
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
}
|
|
|
|
|
|
return $skills;
|
|
|
|
|
|
}
|
|
|
|
public static function get_skill(int $id)
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$skill = $DB->get_record('block_gradelevel_levels', array('id' => $id));
|
|
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
|
|
return $skill;
|
|
|
|
}
|
|
|
|
public static function update_skill(int $id, $name, $icon )
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
|
|
|
|
if($name != null){
|
|
$skill->name = $name;
|
|
}
|
|
|
|
if($icon != null){
|
|
$skill->icon = $icon;
|
|
}
|
|
|
|
$DB->update_record('block_gradelevel_levelset',$skill);
|
|
|
|
|
|
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
|
|
return $skill;
|
|
}
|
|
|
|
public static function add_skill($name, $icon)
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$skill = new stdClass;
|
|
|
|
if(empty($name)){
|
|
$skill->name = get_string('defaults_name','block_gradelevel');
|
|
}
|
|
else {
|
|
$skill->name = $name;
|
|
}
|
|
if(empty($icon)){
|
|
$skill->icon = "/blocks/gradelevel/pix/undefinedskill.svg";
|
|
}
|
|
else {
|
|
$skill->icon = $icon;
|
|
}
|
|
|
|
$id = $DB->insert_record('block_gradelevel_levelset',$skill, true);
|
|
|
|
$skill->id = $id;
|
|
$skill->html = static::single_skill_editor_item(block_gradelevel_levelset::find_by_id($skill->id));
|
|
|
|
return $skill;
|
|
}
|
|
|
|
public static function delete_skill(int $id)
|
|
{
|
|
global $CFG, $DB;
|
|
|
|
$skill = block_gradelevel_levelset::find_by_id($id);
|
|
if(count($skill->list_courses()) > 0)
|
|
{
|
|
throw new Exception("Cannot delete skills that have courses attached");
|
|
}
|
|
|
|
$result = array('id' => $id);
|
|
$result['deleted'] = ($DB->delete_records('block_gradelevel_levelset',array('id' => $id)))?true:false;
|
|
return $result;
|
|
}
|
|
|
|
|
|
// Other public functions
|
|
|
|
public static function render_leveltable($skill_id)
|
|
{
|
|
$levels = static::list_levels($skill_id);
|
|
|
|
$s = "<p>".get_string('levelcfg_description','block_gradelevel')."</p>";
|
|
$s .= "<table id='level_config' class='level_config' data-skill='{$skill_id}'>";
|
|
$s .= "<thead><tr><th>".get_string('levelcfg_head_points','block_gradelevel')."</th><th>".get_string('levelcfg_head_color','block_gradelevel')."</th></tr></thead>";
|
|
$s .= "<tbody>";
|
|
foreach($levels as $lvl)
|
|
{
|
|
$color = ltrim($lvl->badgecolor,"#"); // trim any leading hashes
|
|
$s .= "<tr data-rowid='{$lvl->id}'><td><input data-name='points' type='number' class='uint' value='{$lvl->points}'></td><td><input type='text' data-name='color' class='jscolor' value='{$color}'></td></tr>";
|
|
|
|
}
|
|
$s .= "</tbody>";
|
|
$s .= "<tfoot><tr><td class='block_gradelevel_addlevel' colspan='2'><a data-action='addlevel' href='#' onclick='return false;'>".get_string("levelcfg_addlevel",'block_gradelevel')."</a></td></td></tfoot>";
|
|
$s .= "</table>";
|
|
$s .= "<p><button data-action='savechanges'>".get_string('savechanges','core')."</button>";
|
|
if($skill_id > 0)
|
|
{
|
|
$s .= " <button data-action='resetlevels'>".get_string('cfg_resetlevels','block_gradelevel')."</button>";
|
|
}
|
|
$s .= "</p>";
|
|
|
|
return $s;
|
|
|
|
}
|
|
|
|
public static function render_skill_list()
|
|
{
|
|
global $CFG;
|
|
$skills = block_gradelevel_levelset::list_all();
|
|
|
|
// Sort by points
|
|
usort( $skills, function( $a, $b) {
|
|
return ( $a->getName() < $b->getName()) ? -1 : 1;
|
|
} );
|
|
|
|
$s = "<div id='skill_set' class='skill_set'><ul>";
|
|
foreach($skills as $skill)
|
|
{
|
|
$s .= static::single_skill_editor_item($skill);
|
|
}
|
|
|
|
$s .= "</ul>";
|
|
$s .= "<a href='#' onclick='return false;' data-action='addskill'>".get_string('cfg_addskill','block_gradelevel')."</a>";
|
|
$s .= "</div>";
|
|
|
|
return $s;
|
|
}
|
|
|
|
public static function render_skill_editor(int $skill_id)
|
|
{
|
|
$skill = block_gradelevel_levelset::find_by_id($skill_id);
|
|
|
|
$s = "<div id='skill_set' class='skill_set'><ul>";
|
|
$s .= static::single_skill_editor_item($skill,true);
|
|
$s .= "</ul></div>";
|
|
|
|
return $s;
|
|
}
|
|
|
|
private static function single_skill_editor_item($skill,$single=false)
|
|
{
|
|
global $OUTPUT;
|
|
|
|
$skill_id = $skill->getId();
|
|
$s = "<li class='skill_info' data-id='{$skill_id}'>";
|
|
if(!$single){
|
|
$s .= "<a data-action='editlevels' href='#'>";
|
|
}
|
|
$s .= $skill->render_demo_badge(static::DEMOBADGE_SIZE)."</a>";
|
|
|
|
if(!$single){
|
|
$s .= "<a data-action='editlevels' href='#'>";
|
|
if(count($skill->list_courses()) == 0){
|
|
$s .= "<a class='deleteskill' data-action='deleteskill' onclick='return false;' href='#'><i class='icon fa fa-minus-circle fa-fw' title='".get_string('tooltip_deleteskill','block_gradelevel')."'></i></a>";
|
|
}
|
|
}
|
|
|
|
$s .= "<a class='editicon' data-action='editicon' onclick='return false;' href='#'><i class='icon fa fa-pencil fa-fw' title='".get_string('tooltip_editicon','block_gradelevel')."'></i></a>";
|
|
$s .= "<figcaption data-for='name'><span data-type='label'>".$skill->getName()."</span>";
|
|
$s .= "<a class='editname' data-action='editname' onclick='return false;' href='#'><i class='icon fa fa-pencil fa-fw' title='".get_string('tooltip_editname','block_gradelevel')."'></i></a>";
|
|
$s .= "</figcaption></li>";
|
|
return $s;
|
|
}
|
|
|
|
} |