Added web service for managing levelsets (now mostly called "skills")
Default levels can be configured. Working on management interface for predefined skills.
This commit is contained in:
parent
9452a578bc
commit
6b16559201
|
@ -2,58 +2,116 @@
|
|||
// You can call it anything you like
|
||||
|
||||
define(['jquery', 'core/str', 'core/ajax', 'block_gradelevel/jscolor'], function ($, str, ajax, jscolor) {
|
||||
let skill_id = null;
|
||||
let $skill_table = null;
|
||||
|
||||
let self = {
|
||||
init: function init() {
|
||||
$("input[type=number].uint").on('change', function (evt) {
|
||||
|
||||
// Find skill table and skill id
|
||||
$skill_table = $("table#level_config");
|
||||
skill_id = Number($skill_table.attr('data-skill'));
|
||||
|
||||
if (!skill_id && skill_id !== 0 && skill_id !== '0') {
|
||||
console.error("Cannot find configured skill id");
|
||||
return;
|
||||
}
|
||||
|
||||
// load and fill the level table
|
||||
self.refresh();
|
||||
|
||||
// make sure all uint type numbers are not able to go below 0
|
||||
$(document).on('change', "input[type=number].uint", function (evt) {
|
||||
let $this = $(this);
|
||||
if ($this.val() < 0) {
|
||||
$this.val(0);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// On click handler for add level link
|
||||
$("a[data-action=addlevel]").on('click', function (evt) {
|
||||
let $newtr = $("<tr data-rowid=''>"
|
||||
+ "<td><input data-name='points' type='number' class='uint'></td>"
|
||||
+ "<td><input type='text' data-name='color' class='jscolor' value='7F7F7F'></td></tr>");
|
||||
|
||||
let $tbody = $("table#level_config tbody");
|
||||
|
||||
// apply jscolor to new row
|
||||
$newtr.find("input.jscolor").each(function () {
|
||||
let picker = new jscolor(this);
|
||||
});
|
||||
// and add
|
||||
$tbody.append($newtr);
|
||||
|
||||
|
||||
self.add_levelrow(-255, '', '7F7F7F');
|
||||
});
|
||||
|
||||
// On click handler for save changes button
|
||||
$("button[data-action=savechanges]").on('click', self.submit);
|
||||
|
||||
|
||||
},
|
||||
add_levelrow: function (id, points, color) {
|
||||
// create new row
|
||||
let $newtr = $("<tr data-rowid='"+id+"'>"
|
||||
+ "<td><input data-name='points' type='number' class='uint' value='"+points+"'></td>"
|
||||
+ "<td><input type='text' data-name='color' class='jscolor' value='"+color+"'></td></tr>");
|
||||
|
||||
// apply jscolor to new row
|
||||
$newtr.find("input.jscolor").each(function () {
|
||||
let picker = new jscolor(this);
|
||||
});
|
||||
|
||||
// and add to the body of the table
|
||||
$skill_table.find("tbody").append($newtr);
|
||||
},
|
||||
refresh: function refresh() {
|
||||
console.info("Attempting to refresh");
|
||||
|
||||
// perform refresh call
|
||||
let promises = ajax.call([{
|
||||
methodname: 'block_gradelevel_list_levels',
|
||||
args: { skill_id: skill_id },
|
||||
}]);
|
||||
|
||||
// and link promise returns to callbacks
|
||||
promises[0].done(self.success_refill_table).fail(self.fail_report_exception);
|
||||
},
|
||||
submit: function submit(evt) {
|
||||
let $table = $("table#level_config");
|
||||
|
||||
let data = { skill_id: $table.attr('data-skill'), levels: [] };
|
||||
let level_data = [];
|
||||
$table.find("tbody tr[data-rowid]").each(function () {
|
||||
let $this = $(this);
|
||||
let row = {
|
||||
id: $this.attr('data-rowid'),
|
||||
id: Number($this.attr('data-rowid')),
|
||||
points: $this.find("input[data-name=points]").val(),
|
||||
color: $this.find("input[data-name=color]").val(),
|
||||
badgecolor: $this.find("input[data-name=color]").val(),
|
||||
}
|
||||
data.levels.push(row);
|
||||
|
||||
if (row.points === "") { row.points = -255; }
|
||||
row.points = Number(row.points);
|
||||
|
||||
level_data.push(row);
|
||||
});
|
||||
|
||||
console.info("Attempting to submit", data);
|
||||
//console.info("Attempting to submit", level_data);
|
||||
|
||||
$.post("#", { action: "submitchanges", data: data }, function (result) {
|
||||
console.info('result: ', result);
|
||||
window.location.href = '#';
|
||||
});
|
||||
// perform ajax call
|
||||
let promises = ajax.call([{
|
||||
methodname: 'block_gradelevel_submit_levels',
|
||||
args: { skill_id: skill_id, levels: level_data },
|
||||
}]);
|
||||
|
||||
},
|
||||
// and link promise returns to callbacks
|
||||
promises[0].done(self.success_refill_table).fail(self.fail_report_exception);
|
||||
},
|
||||
success_refill_table: function success_refill_table(response) {
|
||||
//console.info("Response from webservice: ", response);
|
||||
let $tbody = $skill_table.find('tbody');
|
||||
$tbody.empty();
|
||||
for (let idx in response) {
|
||||
let lvl = response[idx];
|
||||
//console.info("Level:", lvl);
|
||||
self.add_levelrow(lvl.id, lvl.points, lvl.badgecolor);
|
||||
}
|
||||
},
|
||||
fail_report_exception: function fail_report_exception(ex) {
|
||||
if (ex.error != undefined) {
|
||||
console.error("Error from webservice: ", ex.error, "\n" , ex.debuginfo, "\n---Stack trace---\n", ex.stacktrace, "\n", ex);
|
||||
}
|
||||
else {
|
||||
console.error("Exception from webservice: ", ex.message, "\n", ex.debuginfo, "\n---Stack trace---\n", ex.backtrace, "\n", ex);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
return self;
|
||||
|
|
|
@ -11,7 +11,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) {
|
|||
let props = self.fetchProperties(this);
|
||||
let $this = $(this);
|
||||
let $canvas = $("<canvas height= '"+props.height +"' width = '"+props.width+"'/>");
|
||||
console.info("$canvas", $canvas, $canvas[0]);
|
||||
//console.info("$canvas", $canvas, $canvas[0]);
|
||||
$('canvas', this).remove();// clear out any existing canvas
|
||||
$this.append($canvas); // Put the canvas in there
|
||||
self.render($canvas[0], props);
|
||||
|
@ -61,9 +61,9 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) {
|
|||
scale: 0.7, // scale to this fraction of image size
|
||||
}
|
||||
}
|
||||
console.info("Config", config);
|
||||
console.info("Colors", colors);
|
||||
console.info("Props", props);
|
||||
//console.info("Config", config);
|
||||
//console.info("Colors", colors);
|
||||
//console.info("Props", props);
|
||||
|
||||
// draw main circle
|
||||
let baseGradient = ctx.createRadialGradient(
|
||||
|
@ -159,7 +159,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) {
|
|||
|
||||
ctx.drawImage(this, 15, 15, 120, 120);//imPos.x, imPos.y, imPos.w, imPos.h);
|
||||
}
|
||||
console.info("Image: ",props.image);
|
||||
//console.info("Image: ",props.image);
|
||||
iconImg.src = props.image;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) {
|
|||
progress: $figure.attr("data-progress"),
|
||||
width: $figure.attr("data-width"),
|
||||
height: $figure.attr("data-height"),
|
||||
color: $figure.attr("data-color"),
|
||||
color: "#"+$figure.attr("data-color"),
|
||||
level: $figure.attr("data-level"),
|
||||
image: image,
|
||||
};
|
||||
|
|
|
@ -44,6 +44,7 @@ class block_gradelevel extends block_base {
|
|||
|
||||
public function get_content() {
|
||||
global $USER;
|
||||
global $COURSE;
|
||||
|
||||
if ($this->content !== null) {
|
||||
return $this->content;
|
||||
|
@ -55,7 +56,7 @@ class block_gradelevel extends block_base {
|
|||
$pointstotal = $this->levelset->get_levelset_grade($USER->id);
|
||||
$level_info = $this->levelset->calculate_level($pointstotal);
|
||||
|
||||
$this->content->text = $this->render_badge($level_info->badge_color,$level_info->progress,$this->levelset->getIcon(),$level_info->level);
|
||||
$this->content->text = $this->levelset->render_badge($pointstotal);
|
||||
|
||||
if($level_info->levelup_total > 0)
|
||||
{
|
||||
|
@ -66,38 +67,23 @@ class block_gradelevel extends block_base {
|
|||
$this->content->footer = "<div class='pointinfo complete'>".get_string('levelup_done','block_gradelevel')."</div>";
|
||||
}
|
||||
|
||||
|
||||
$coursecontext = context_course::instance($COURSE->id);
|
||||
|
||||
if(has_capability('block/gradelevel:viewresults', $coursecontext))
|
||||
{
|
||||
$this->content->footer .= "\n<div class='teachermode'><a href='#'>".get_string('teacher_view_results','block_gradelevel')."</a></div>";
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
||||
public function hide_header() { return false; }
|
||||
public function hide_header() { return !get_config('gradelevel', 'showtitle'); }
|
||||
|
||||
public function has_config() { return true; }
|
||||
|
||||
|
||||
private function render_badge($basecolor,$progress,$image=null,$level="1"){
|
||||
global $CFG;
|
||||
if(strncmp($image,"data: ",6) != 0)
|
||||
{
|
||||
$image_url = $CFG->wwwroot.$image;
|
||||
}
|
||||
else
|
||||
{
|
||||
$image_url = $image;
|
||||
}
|
||||
|
||||
|
||||
$html = "<figure class='levelbadge' data-color='{$basecolor}' data-progress='{$progress}' data-width='150' data-height='150' data-level='{$level}'>";
|
||||
if(!empty($image))
|
||||
{
|
||||
$html .= "<img style='display:none' src='{$image_url}' />";
|
||||
}
|
||||
$html .= "</figure>";
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -10,11 +10,11 @@ class block_gradelevel_levelset {
|
|||
const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg";
|
||||
|
||||
const GLOBAL_DEFAULTS = array(
|
||||
0 => "#000000",
|
||||
25 => "#2ad4ff",
|
||||
50 => "#cd7f32",
|
||||
100 => "#a6a6a6",
|
||||
200 => "#f6ae00",
|
||||
0 => "#000000",
|
||||
250 => "#2ad4ff", // + 250
|
||||
750 => "#cd7f32", // + 500
|
||||
1750 => "#a6a6a6", // + 1000
|
||||
2750 => "#f6ae00", // + 2000
|
||||
);
|
||||
|
||||
private $id;
|
||||
|
@ -85,6 +85,11 @@ class block_gradelevel_levelset {
|
|||
|
||||
}
|
||||
|
||||
public function getId() : string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->data->name = $name;
|
||||
|
@ -136,6 +141,19 @@ class block_gradelevel_levelset {
|
|||
return null; // return null if no current levelset linked
|
||||
}
|
||||
|
||||
static public function find_by_id($id)
|
||||
{
|
||||
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => array_values($records)[0]->levelset_id));
|
||||
if($levelset)
|
||||
{
|
||||
return new static($levelset->id,$levelset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List attached courses for this levelset
|
||||
|
@ -190,8 +208,6 @@ class block_gradelevel_levelset {
|
|||
print_error('updateerror', 'block_gradelevel');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -436,4 +452,43 @@ class block_gradelevel_levelset {
|
|||
|
||||
}
|
||||
|
||||
public function render_badge(int $points,int $size=150){
|
||||
global $CFG;
|
||||
|
||||
$info = $this->calculate_level($points);
|
||||
|
||||
$image = $this->getIcon();
|
||||
if(strncmp($image,"data: ",6) != 0)
|
||||
{
|
||||
$image_url = $CFG->wwwroot.$image;
|
||||
}
|
||||
else
|
||||
{
|
||||
$image_url = $image;
|
||||
}
|
||||
|
||||
$html = "<figure class='levelbadge'";
|
||||
$html .= " data-color='{$info->badge_color}'";
|
||||
$html .= " data-progress='{$info->progress}'";
|
||||
$html .= " data-level='{$info->level}'";
|
||||
$html .= " data-width='{$size}'";
|
||||
$html .= " data-height='{$size}'";
|
||||
$html .= ">";
|
||||
if(!empty($image))
|
||||
{
|
||||
$html .= "<img style='display:none' src='{$image_url}' />";
|
||||
}
|
||||
$html .= "</figure>";
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function render_demo_badge(int $size=100)
|
||||
{
|
||||
$levels = $this->badgelevels();
|
||||
$maxpoints = array_pop(array_keys($levels));
|
||||
|
||||
return $this->render_badge($maxpoints,$size);
|
||||
|
||||
}
|
||||
|
||||
}
|
406
classes/skillmgmtservice.php
Normal file
406
classes/skillmgmtservice.php
Normal file
|
@ -0,0 +1,406 @@
|
|||
<?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 = 100; // 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);
|
||||
|
||||
if(skill_id == 0)
|
||||
{
|
||||
// Check if user has capability to manage global levels
|
||||
require_capability('block/gradelevel:managelevels', $systemcontext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if user has teacher or manager capability in any of the attached courses
|
||||
$capability = false;
|
||||
$courses = self::list_courses($skill_id);
|
||||
foreach($courses as $course_id)
|
||||
{
|
||||
$coursecontext = context_course::instance($course_id);
|
||||
$capability |= has_capability('block/gradelevel:changelevels', $coursecontext);
|
||||
}
|
||||
|
||||
if(!$capability)
|
||||
{
|
||||
throw new Exception("Access denied - you do not have editing capabilities for one of the attached courses");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
|
||||
// Sort by points
|
||||
usort( $levels, function( $a, $b) {
|
||||
return ( $a->points < $b->points ) ? -1 : 1;
|
||||
} );
|
||||
|
||||
|
||||
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, string $name, string $icon )
|
||||
{
|
||||
global $CFG, $DB;
|
||||
|
||||
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
|
||||
|
||||
$skill->name = $name;
|
||||
$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(string $name, string $icon)
|
||||
{
|
||||
global $CFG, $DB;
|
||||
|
||||
$skill = stdObj;
|
||||
|
||||
$skill->name = $name;
|
||||
$skill->icon = $icon;
|
||||
|
||||
$id = $DB->insert_record('block_gradelevel_levelset',$skill, true);
|
||||
|
||||
$skill->id = $id;
|
||||
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
||||
|
||||
return $skill;
|
||||
}
|
||||
|
||||
public static function delete_skill(int $id)
|
||||
{
|
||||
global $CFG, $DB;
|
||||
|
||||
$result = stdObj;
|
||||
$result->id = $id;
|
||||
|
||||
$result->id = ($DB->delete_record('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' 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></p>";
|
||||
|
||||
return $s;
|
||||
|
||||
}
|
||||
|
||||
public static function render_skill_list()
|
||||
{
|
||||
$skills = block_gradelevel_levelset::list_all();
|
||||
|
||||
$s = "<div class='skill_set'><ul>";
|
||||
foreach($skills as $skill)
|
||||
{
|
||||
$skill_id = $skill->getId();
|
||||
$s .= "<li class='skill_info' data-id='{$skill_id}'>".$skill->render_demo_badge(DEMOBADGE_SIZE);
|
||||
$s .= "<figcaption data-for='name'>".$skill->getName()."</figcaption>";
|
||||
$s .= "</li>";
|
||||
}
|
||||
|
||||
$s .= "</ul></div>";
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -23,4 +23,27 @@
|
|||
|
||||
'clonepermissionsfrom' => 'moodle/site:manageblocks'
|
||||
),
|
||||
|
||||
'block/gradelevel:skillmanager' => array(
|
||||
'riskbitmask' => RISK_CONFIG | RISK_DATALOSS | RISK_XSS,
|
||||
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
),
|
||||
|
||||
'block/gradelevel:viewresults' => array(
|
||||
'riskbitmask' => RISK_DATALOSS | RISK_XSS,
|
||||
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_BLOCK,
|
||||
'archetypes' => array(
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
|
||||
),
|
||||
|
||||
);
|
|
@ -21,7 +21,7 @@
|
|||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="levelset_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Reference to specific levelset"/>
|
||||
<FIELD NAME="points" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Number of points needed to reach this level"/>
|
||||
<FIELD NAME="bagdecolor" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Color of the level badge. Leave null to use default color (of the levelset 0 set)"/>
|
||||
<FIELD NAME="badgecolor" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Color of the level badge. Leave null to use default color (of the levelset 0 set)"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
|
|
93
db/services.php
Normal file
93
db/services.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
$services = array(
|
||||
"Gradelevel Level Management" => array(
|
||||
'functions' => array('block_gradelevel_submit_levels', 'block_gradelevel_list_levels'),
|
||||
'requiredcapability' => 'block/gradelevel:changelevels',
|
||||
'shortname'=> 'block_gradelevel_levelmgmt',
|
||||
'restrictedusers' => 0,
|
||||
'enabled' => 0,
|
||||
'ajax' => true,
|
||||
),
|
||||
);
|
||||
|
||||
$functions = array(
|
||||
'block_gradelevel_submit_levels' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'submit_levels', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'Update level settings for a given skill', //human readable description of the web service function
|
||||
'type' => 'write', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_list_levels' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'list_levels', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'List level settings for a given skill', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_list_skills' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'list_skills', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'List skills', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_get_skill' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'get_skill', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'Retrieve skill information', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_update_skill' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'update_skill', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'Update a skill', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_add_skill' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'add_skill', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'Add a new skill', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
'block_gradelevel_delete_skill' => array( //web service function name
|
||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
||||
'methodname' => 'delete_skill', //external function name
|
||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
||||
'description' => 'Delete a skill', //human readable description of the web service function
|
||||
'type' => 'read', //database rights of the web service function (read, write)
|
||||
'ajax' => true,
|
||||
'capabilities' => 'block/gradelevel:skillmanager',
|
||||
'loginrequired' => true,
|
||||
'services' => array('block_gradelevel_levelmgmt'),
|
||||
),
|
||||
|
||||
);
|
|
@ -157,7 +157,6 @@ COURSE: stdClass Object
|
|||
[shortname] => PIC-MCU3
|
||||
[idnumber] =>
|
||||
[summary] => Programmeren van PIC18 microcontrollers van microchip.
|
||||
|
||||
[summaryformat] => 1
|
||||
[format] => topics
|
||||
[showgrades] => 1
|
||||
|
|
|
@ -29,7 +29,9 @@ class block_gradelevel_edit_form extends block_edit_form {
|
|||
$mform->addElement('filepicker', 'levelset_icon', get_string('levelset_icon_new', 'block_gradelevel'), null,
|
||||
array('maxbytes' => $maxbytes, 'accepted_types' => array('.png', '.svg')));
|
||||
|
||||
|
||||
$mform->addElement('header', 'config_header', get_string('levelset_levels', 'block_gradelevel'));
|
||||
$mform->addElement('html',print block_gradelevel_managelevelservice::render_leveltable(0));
|
||||
|
||||
}
|
||||
|
||||
public function set_data($defaults)
|
||||
|
|
|
@ -3,6 +3,7 @@ if(isset($_SERVER['SCRIPT_FILENAME']))
|
|||
{
|
||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
||||
error_log("Using {$root}/config.php");
|
||||
require_once($root."/config.php");
|
||||
}
|
||||
else
|
||||
|
@ -15,61 +16,19 @@ else
|
|||
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
|
||||
admin_externalpage_setup("block_gradelevel_default_levels");
|
||||
|
||||
$action = optional_param('action', null, PARAM_ALPHA);
|
||||
$data = optional_param('data', null, PARAM_ALPHA);
|
||||
if(!empty($data))
|
||||
{
|
||||
$data = json_decode($data);
|
||||
}
|
||||
|
||||
if(!empty($action) && confirm_sesskey())
|
||||
{
|
||||
switch($action) {
|
||||
case 'submitchanges':
|
||||
|
||||
print_r($data);
|
||||
$systemcontext = context_system::instance();
|
||||
// Check if user has capability to manage skills
|
||||
require_capability('block/gradelevel:skillmanager', $systemcontext);
|
||||
|
||||
|
||||
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
|
||||
|
||||
print $OUTPUT->header();
|
||||
print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel'));
|
||||
|
||||
|
||||
|
||||
redirect($PAGE->url);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
|
||||
|
||||
print $OUTPUT->header();
|
||||
print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel'));
|
||||
|
||||
$global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
|
||||
usort( $global_levels, function( $a, $b) {
|
||||
return ( $a->points < $b->points ) ? -1 : 1;
|
||||
} );
|
||||
|
||||
$skill_id = 0;
|
||||
print "<p>".get_string('levelcfg_description','block_gradelevel')."</p>";
|
||||
print "<table id='level_config' data-skill='{$skill_id}'>";
|
||||
print "<thead><tr><th>".get_string('levelcfg_head_points','block_gradelevel')."</th><th>".get_string('levelcfg_head_color','block_gradelevel')."</th></tr></thead>";
|
||||
print "<tbody>";
|
||||
foreach($global_levels as $lvl)
|
||||
{
|
||||
$color = ltrim($lvl->badgecolor,"#");
|
||||
print "<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>";
|
||||
|
||||
}
|
||||
print "</tbody>";
|
||||
print "<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>";
|
||||
print "</table>";
|
||||
print "<p><button data-action='savechanges'>".get_string('savechanges','core')."</button></p>";
|
||||
|
||||
|
||||
|
||||
print $OUTPUT->footer();
|
||||
}
|
||||
// render page for skill level 0 (global)
|
||||
print block_gradelevel_skillmgmtservice::render_leveltable(0);
|
||||
print $OUTPUT->footer();
|
||||
|
|
|
@ -8,6 +8,8 @@ $string['blockstring'] = 'Text in the block';
|
|||
$string['levelup_at'] = 'Next level: ';
|
||||
$string['levelup_done'] = 'Complete';
|
||||
|
||||
$string['teacher_view_results'] = 'View student results';
|
||||
|
||||
$string['levelset_name'] = "Skill name";
|
||||
$string['levelset_icon_cur'] = "Current skill icon (for level badge)";
|
||||
$string['levelset_icon_new'] = "New skill icon (for level badge)";
|
||||
|
|
|
@ -17,6 +17,9 @@ div.pointinfo {
|
|||
div.pointinfo span.leveluppoints {
|
||||
font-weight: bold;
|
||||
}
|
||||
div.teachermode {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td.block_gradelevel_addlevel {
|
||||
text-align: right;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
$plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
||||
$plugin->version = 2018091600; // YYYYMMDDHH (year, month, day, 24-hr time)
|
||||
$plugin->version = 2018092101; // YYYYMMDDHH (year, month, day, 24-hr time)
|
||||
$plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5)
|
Loading…
Reference in New Issue
Block a user