Lot of stuff and fixed Edge not accepting #RRGGBBAA notation issue latest

This commit is contained in:
user 2018-11-24 12:34:30 +01:00
parent fa8dd4b653
commit 73e45df3fc
29 changed files with 2948 additions and 2906 deletions

3
.vs/ProjectSettings.json Normal file
View File

@ -0,0 +1,3 @@
{
"CurrentProjectSetting": null
}

14
.vs/VSWorkspaceState.json Normal file
View File

@ -0,0 +1,14 @@
{
"ExpandedNodes": [
"",
"\\amd",
"\\classes",
"\\db",
"\\lang",
"\\lang\\en",
"\\lang\\nl",
"\\pix"
],
"SelectedNode": "\\db\\access.php",
"PreviewInSolutionExplorer": false
}

Binary file not shown.

BIN
.vs/slnx.sqlite Normal file

Binary file not shown.

12
LICENSE
View File

@ -1,7 +1,7 @@
Copyright 2018 P.M. Kuipers
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Copyright 2018 P.M. Kuipers
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1 +1 @@
define(["jquery","core/str","core/ajax","block_gradelevel/debugger"],function(e,t,i,l){let r=l("renderbadge");r.enable();let a={init:function(){r.info("Setting up badge renderers"),e("figure.levelbadge").each(function(){a.setup_badge(this,!0)})},setup_badge:function(t,i){let l=e(t),n=e(t).data("badge-props");if(r.info("Setting up skill badge on ",t,n),n&&i)r.info(" skill badge was already configured. Skipping process...");else{n=a.fetchProperties(t);let i=e("<canvas height= '"+n.height+"' width = '"+n.width+"'/>");e("canvas",t).remove(),l.append(i),a.render(i[0],n),l.data("badge-props",n)}},render:function(e,t){let i=e.getContext("2d"),l={base:t.color,light:a.shadeBlendConvert(.6,t.color),dark:a.shadeBlendConvert(.3,t.color),lightPoint:a.shadeBlendConvert(.8,t.color),reflection:{lightest:"#ffffff51",darkest:"#ffffff20"},radialGradient:{x0:.75,y0:.25,r0:.05,x1:.6,y1:.4,r1:.4},levelText:"white"},n={size:Math.min(t.height,t.width),borderWidth:.05,reflection:{angle:-20,offset:.125},levelText:{x:.5,y:.9,size:.2,font:"Open Sans, Arial, helvetica, sans-serif"},icon:{x:.5,y:.47,scale:.7}};r.info(" Config",n),r.info(" Colors",l),r.info(" Props",t);let s=i.createRadialGradient(n.size*l.radialGradient.x0,n.size*l.radialGradient.y0,n.size*l.radialGradient.r0,n.size*l.radialGradient.x1,n.size*l.radialGradient.y1,n.size*l.radialGradient.r1);s.addColorStop(0,l.lightPoint),s.addColorStop(1,l.base),i.beginPath(),i.fillStyle=s,i.arc(.5*n.size,.5*n.size,n.size/2,0,2*Math.PI),i.fill();let o=Math.asin(n.reflection.offset),d=n.reflection.angle/360*2*Math.PI,h=i.createLinearGradient((.5-n.reflection.offset*Math.sin(d))/2*n.size,(.5+n.reflection.offset*Math.cos(d))/2*n.size,Math.sin(d)/2*n.size,Math.cos(d)/2*n.size);h.addColorStop(0,l.reflection.lightest),h.addColorStop(1,l.reflection.darkest),i.beginPath(),i.fillStyle=h,i.arc(.5*n.size,.5*n.size,n.size/2,0+o+d,Math.PI-o+d),i.fill();let f=n.size*n.borderWidth;if(i.beginPath(),i.strokeStyle=l.light,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0,2*Math.PI),i.stroke(),i.beginPath(),i.strokeStyle=l.dark,i.lineWidth=f,i.arc(.5*n.size,.5*n.size,n.size/2-f/2,0-Math.PI/2,2*t.progress*Math.PI-Math.PI/2),i.stroke(),t.level&&(i.font=n.size*n.levelText.size+"px "+n.levelText.font,i.fillStyle=l.levelText,i.textAlign="center",i.fillText(""+t.level,n.size*n.levelText.x,n.size*n.levelText.y)),t.image){let e=new Image;e.onload=function(){let e={x:0,y:0,w:n.size*n.icon.scale,h:n.size*n.icon.scale};this.width>this.height?e.h*=this.height/this.width:e.w*=this.width/this.height,e.x=n.size*n.icon.x-e.w/2,e.y=n.size*n.icon.y-e.h/2,i.drawImage(this,e.x,e.y,e.w,e.h)},e.src=t.image}},fetchProperties:function(t){let i=e(t),l=i.find("img"),r=null;return l.length>0&&(r=l.attr("src")),{progress:i.attr("data-progress"),width:i.attr("data-width"),height:i.attr("data-height"),color:"#"+i.attr("data-color"),level:i.attr("data-level"),image:r}},shadeBlendConvert:function(e,t,i){if("number"!=typeof e||e<-1||e>1||"string"!=typeof t||"r"!=t[0]&&"#"!=t[0]||i&&"string"!=typeof i)return null;this.sbcRip||(this.sbcRip=(e=>{let t=e.length,i={};if(t>9){if((e=e.split(",")).length<3||e.length>4)return null;i[0]=l(e[0].split("(")[1]),i[1]=l(e[1]),i[2]=l(e[2]),i[3]=e[3]?parseFloat(e[3]):-1}else{if(8==t||6==t||t<4)return null;t<6&&(e="#"+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]+(t>4?e[4]+""+e[4]:"")),e=l(e.slice(1),16),i[0]=e>>16&255,i[1]=e>>8&255,i[2]=255&e,i[3]=-1,9!=t&&5!=t||(i[3]=r(i[2]/255*1e4)/1e4,i[2]=i[1],i[1]=i[0],i[0]=e>>24&255)}return i}));var l=parseInt,r=Math.round,a=t.length>9,n=(a="string"==typeof i?i.length>9||"c"==i&&!a:a,e<0),s=(e=n?-1*e:e,i=i&&"c"!=i?i:n?"#000000":"#FFFFFF",this.sbcRip(t)),o=this.sbcRip(i);return s&&o?a?"rgb"+(s[3]>-1||o[3]>-1?"a(":"(")+r((o[0]-s[0])*e+s[0])+","+r((o[1]-s[1])*e+s[1])+","+r((o[2]-s[2])*e+s[2])+(s[3]<0&&o[3]<0?")":","+(s[3]>-1&&o[3]>-1?r(1e4*((o[3]-s[3])*e+s[3]))/1e4:o[3]<0?s[3]:o[3])+")"):"#"+(4294967296+16777216*r((o[0]-s[0])*e+s[0])+65536*r((o[1]-s[1])*e+s[1])+256*r((o[2]-s[2])*e+s[2])+(s[3]>-1&&o[3]>-1?r(255*((o[3]-s[3])*e+s[3])):o[3]>-1?r(255*o[3]):s[3]>-1?r(255*s[3]):255)).toString(16).slice(1,s[3]>-1||o[3]>-1?void 0:-2):null}};return a});
define(["jquery","core/str","core/ajax","block_gradelevel/debugger"],function(e,t,i,r){let l=r("renderbadge");function n(e){if(/^#([A-Fa-f0-9]{3})$/.test(e)){let t=e.substring(1).split(""),i="0x"+[t[0],t[0],t[1],t[1],t[2],t[2]].join("");return"rgb("+[i>>16&255,i>>8&255,255&i].join(",")+")"}if(/^#([A-Fa-f0-9]{6})$/.test(e)){let t="0x"+e.substring(1).split("").join("");return"rgb("+[t>>16&255,t>>8&255,255&t].join(",")+")"}if(/^#([A-Fa-f0-9]{8})$/.test(e)){let t=e.substring(1).split(""),i="0x"+[t[0],t[1],t[2],t[3],t[4],t[5]].join(""),r="0x"+[t[6],t[7]].join("");return"rgba("+[i>>16&255,i>>8&255,255&i].join(",")+","+r/255+")"}throw Error("Invalid hex code: "+e)}l.enable();let a={init:function(){l.info("Setting up badge renderers"),e("figure.levelbadge").each(function(){a.setup_badge(this,!0)})},setup_badge:function(t,i){let r=e(t),n=e(t).data("badge-props");if(l.info("Setting up skill badge on ",t,n),n&&i)l.info(" skill badge was already configured. Skipping process...");else{n=a.fetchProperties(t);let i=e("<canvas height= '"+n.height+"' width = '"+n.width+"'/>");e("canvas",t).remove(),r.append(i),a.render(i[0],n),r.data("badge-props",n)}},render:function(e,t){let i=e.getContext("2d"),r={base:t.color,light:a.shadeBlendConvert(.6,t.color),dark:a.shadeBlendConvert(.3,t.color),lightPoint:a.shadeBlendConvert(.8,t.color),reflection:{lightest:"#ffffff51",darkest:"#ffffff20"},radialGradient:{x0:.75,y0:.25,r0:.05,x1:.6,y1:.4,r1:.4},levelText:"white"},s={size:Math.min(t.height,t.width),borderWidth:.05,reflection:{angle:-20,offset:.125},levelText:{x:.5,y:.9,size:.2,font:"Open Sans, Arial, helvetica, sans-serif"},icon:{x:.5,y:.47,scale:.7}};l.info(" Config",s),l.info(" Colors",r),l.info(" Props",t);let o=i.createRadialGradient(s.size*r.radialGradient.x0,s.size*r.radialGradient.y0,s.size*r.radialGradient.r0,s.size*r.radialGradient.x1,s.size*r.radialGradient.y1,s.size*r.radialGradient.r1);o.addColorStop(0,n(r.lightPoint)),o.addColorStop(1,n(r.base)),i.beginPath(),i.fillStyle=o,i.arc(.5*s.size,.5*s.size,s.size/2,0,2*Math.PI),i.fill();let d=Math.asin(s.reflection.offset),h=s.reflection.angle/360*2*Math.PI;l.info("rflAngleRad:",h);let f=i.createLinearGradient((.5-s.reflection.offset*Math.sin(h))/2*s.size,(.5+s.reflection.offset*Math.cos(h))/2*s.size,Math.sin(h)/2*s.size,Math.cos(h)/2*s.size);l.info("rflGradient",f),f.addColorStop(0,n(r.reflection.lightest)),f.addColorStop(1,n(r.reflection.darkest)),i.beginPath(),i.fillStyle=f,i.arc(.5*s.size,.5*s.size,s.size/2,0+d+h,Math.PI-d+h),i.fill(),l.info("Starting with border");let g=s.size*s.borderWidth;if(i.beginPath(),i.strokeStyle=r.light,i.lineWidth=g,i.arc(.5*s.size,.5*s.size,s.size/2-g/2,0,2*Math.PI),i.stroke(),i.beginPath(),i.strokeStyle=r.dark,i.lineWidth=g,i.arc(.5*s.size,.5*s.size,s.size/2-g/2,0-Math.PI/2,2*t.progress*Math.PI-Math.PI/2),i.stroke(),t.level&&(i.font=s.size*s.levelText.size+"px "+s.levelText.font,i.fillStyle=r.levelText,i.textAlign="center",i.fillText(""+t.level,s.size*s.levelText.x,s.size*s.levelText.y)),t.image){let e=new Image;e.onload=function(){let e={x:0,y:0,w:s.size*s.icon.scale,h:s.size*s.icon.scale};this.width>this.height?e.h*=this.height/this.width:e.w*=this.width/this.height,e.x=s.size*s.icon.x-e.w/2,e.y=s.size*s.icon.y-e.h/2,i.drawImage(this,e.x,e.y,e.w,e.h)},e.src=t.image}},fetchProperties:function(t){let i=e(t),r=i.find("img"),l=null;return r.length>0&&(l=r.attr("src")),{progress:i.attr("data-progress"),width:i.attr("data-width"),height:i.attr("data-height"),color:"#"+i.attr("data-color"),level:i.attr("data-level"),image:l}},shadeBlendConvert:function(e,t,i){if("number"!=typeof e||e<-1||e>1||"string"!=typeof t||"r"!=t[0]&&"#"!=t[0]||i&&"string"!=typeof i)return null;this.sbcRip||(this.sbcRip=(e=>{let t=e.length,i={};if(t>9){if((e=e.split(",")).length<3||e.length>4)return null;i[0]=r(e[0].split("(")[1]),i[1]=r(e[1]),i[2]=r(e[2]),i[3]=e[3]?parseFloat(e[3]):-1}else{if(8==t||6==t||t<4)return null;t<6&&(e="#"+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]+(t>4?e[4]+""+e[4]:"")),e=r(e.slice(1),16),i[0]=e>>16&255,i[1]=e>>8&255,i[2]=255&e,i[3]=-1,9!=t&&5!=t||(i[3]=l(i[2]/255*1e4)/1e4,i[2]=i[1],i[1]=i[0],i[0]=e>>24&255)}return i}));var r=parseInt,l=Math.round,n=t.length>9,a=(n="string"==typeof i?i.length>9||"c"==i&&!n:n,e<0),s=(e=a?-1*e:e,i=i&&"c"!=i?i:a?"#000000":"#FFFFFF",this.sbcRip(t)),o=this.sbcRip(i);return s&&o?n?"rgb"+(s[3]>-1||o[3]>-1?"a(":"(")+l((o[0]-s[0])*e+s[0])+","+l((o[1]-s[1])*e+s[1])+","+l((o[2]-s[2])*e+s[2])+(s[3]<0&&o[3]<0?")":","+(s[3]>-1&&o[3]>-1?l(1e4*((o[3]-s[3])*e+s[3]))/1e4:o[3]<0?s[3]:o[3])+")"):"#"+(4294967296+16777216*l((o[0]-s[0])*e+s[0])+65536*l((o[1]-s[1])*e+s[1])+256*l((o[2]-s[2])*e+s[2])+(s[3]>-1&&o[3]>-1?l(255*((o[3]-s[3])*e+s[3])):o[3]>-1?l(255*o[3]):s[3]>-1?l(255*s[3]):255)).toString(16).slice(1,s[3]>-1||o[3]>-1?void 0:-2):null}};return a});

View File

@ -7,6 +7,29 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
let debug = Debugger("renderbadge");
debug.enable();
// function is used to overcome Edge's non-support of CSS4 hex rgba notation (@nov 2018)
/* eslint-disable no-bitwise*/
function hexToRgbA(hex){
/*eslint no-bitwise: "off"*/
if(/^#([A-Fa-f0-9]{3})$/.test(hex)){
let h= hex.substring(1).split('');
let c= '0x'+[h[0], h[0], h[1], h[1], h[2], h[2]].join('');
return 'rgb('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+')';
}
if(/^#([A-Fa-f0-9]{6})$/.test(hex)){
let h= hex.substring(1).split('');
let c= '0x'+h.join('');
return 'rgb('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+')';
}
if(/^#([A-Fa-f0-9]{8})$/.test(hex)){
let h= hex.substring(1).split('');
let c = '0x' + [h[0],h[1],h[2],h[3],h[4],h[5],].join('');
let a= '0x' + [h[6],h[7],].join('');
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+a/255.0+')';
}
throw Error('Invalid hex code: ' + hex);
}
/* eslint-enable no-bitwise */
let self = {
init: function init() {
debug.info("Setting up badge renderers");
@ -90,8 +113,8 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
config.size * colors.radialGradient.y1,
(config.size ) * colors.radialGradient.r1
);
baseGradient.addColorStop(0, colors.lightPoint);
baseGradient.addColorStop(1, colors.base);
baseGradient.addColorStop(0, hexToRgbA(colors.lightPoint));
baseGradient.addColorStop(1, hexToRgbA(colors.base));
ctx.beginPath();
ctx.fillStyle = baseGradient;
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2, 0, 2 * Math.PI);
@ -102,21 +125,23 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
let rflOffset = Math.asin(config.reflection.offset);
let rflAngleRad = (config.reflection.angle / 360.0) * 2 * Math.PI;
debug.info("rflAngleRad:",rflAngleRad);
let rflGradient = ctx.createLinearGradient(
(0.5 - config.reflection.offset * Math.sin(rflAngleRad))/2 * config.size,
(0.5 + config.reflection.offset * Math.cos(rflAngleRad))/2 * config.size,
Math.sin(rflAngleRad)/2 * config.size,
Math.cos(rflAngleRad)/2 * config.size
);
rflGradient.addColorStop(0, colors.reflection.lightest);
rflGradient.addColorStop(1, colors.reflection.darkest);
debug.info("rflGradient",rflGradient);
rflGradient.addColorStop(0, hexToRgbA(colors.reflection.lightest));
rflGradient.addColorStop(1, hexToRgbA(colors.reflection.darkest));
ctx.beginPath();
ctx.fillStyle = rflGradient;
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2,
0 + rflOffset + rflAngleRad,
Math.PI - rflOffset + rflAngleRad);
ctx.fill();
debug.info("Starting with border");
// draw empty border
let strokeWidth = config.size * config.borderWidth;
ctx.beginPath();

View File

@ -1,89 +1,89 @@
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
use block_gradelevel;
class block_gradelevel extends block_base {
public $levelset;
public function init() {
global $PAGE;
global $COURSE;
$this->title = get_config('gradelevel', 'blocktitle');
if(empty($this->title))
{
$this->title = get_string('title', 'block_gradelevel');
}
// include javascript and run badge renderer when page loading is complete
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
// find or create the levelset for this course
$this->levelset = block_gradelevel_levelset::find_by_course($COURSE->id);
}
// The PHP tag and the curly bracket for the class definition
// will only be closed after there is another function added in the next section.
public function html_attributes() {
$attributes = parent::html_attributes(); // Get default values
$attributes['class'] .= ' block_'. $this->name(); // Append our class to class attribute
return $attributes;
}
public function get_content() {
global $CFG;
global $USER;
global $COURSE;
if ($this->content !== null) {
return $this->content;
}
$this->content = new stdClass;
if(empty($this->levelset))
{
$this->content->text = "<figure class='dummybadge'><img height='150px' width='150px' src='{$CFG->wwwroot}/blocks/gradelevel/pix/brokenbadge.svg' /></figure>";
$this->content->footer = get_string("unattached_course",'block_gradelevel');
}
else {
// below can be a single call to $this->levelset->get_user_leveldata() once the need for debugging (fixed point total) is gone
$pointstotal = $this->levelset->get_levelset_grade($USER->id);
$level_info = $this->levelset->calculate_level($pointstotal);
$this->content->text = $this->levelset->render_badge($pointstotal);
if($level_info->levelup_total > 0)
{
$this->content->footer = "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
}
else
{
$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='{$CFG->wwwroot}/blocks/gradelevel/view-results.php?courseid={$COURSE->id}'>".get_string('teacher_view_results','block_gradelevel')."</a></div>";
}
}
return $this->content;
}
public function hide_header() { return !get_config('gradelevel', 'showtitle'); }
public function has_config() { return true; }
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
use block_gradelevel;
class block_gradelevel extends block_base {
public $levelset;
public function init() {
global $PAGE;
global $COURSE;
$this->title = get_config('gradelevel', 'blocktitle');
if(empty($this->title))
{
$this->title = get_string('title', 'block_gradelevel');
}
// include javascript and run badge renderer when page loading is complete
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
// find or create the levelset for this course
$this->levelset = block_gradelevel_levelset::find_by_course($COURSE->id);
}
// The PHP tag and the curly bracket for the class definition
// will only be closed after there is another function added in the next section.
public function html_attributes() {
$attributes = parent::html_attributes(); // Get default values
$attributes['class'] .= ' block_'. $this->name(); // Append our class to class attribute
return $attributes;
}
public function get_content() {
global $CFG;
global $USER;
global $COURSE;
if ($this->content !== null) {
return $this->content;
}
$this->content = new stdClass;
if(empty($this->levelset))
{
$this->content->text = "<figure class='dummybadge'><img height='150px' width='150px' src='{$CFG->wwwroot}/blocks/gradelevel/pix/brokenbadge.svg' /></figure>";
$this->content->footer = get_string("unattached_course",'block_gradelevel');
}
else {
// below can be a single call to $this->levelset->get_user_leveldata() once the need for debugging (fixed point total) is gone
$pointstotal = $this->levelset->get_levelset_grade($USER->id);
$level_info = $this->levelset->calculate_level($pointstotal);
$this->content->text = $this->levelset->render_badge($pointstotal);
if($level_info->levelup_total > 0)
{
$this->content->footer = "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
}
else
{
$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='{$CFG->wwwroot}/blocks/gradelevel/view-results.php?courseid={$COURSE->id}'>".get_string('teacher_view_results','block_gradelevel')."</a></div>";
}
}
return $this->content;
}
public function hide_header() { return !get_config('gradelevel', 'showtitle'); }
public function has_config() { return true; }
}

View File

@ -1,34 +1,34 @@
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_default_levels");
$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'));
// render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_leveltable(0);
print $OUTPUT->footer();
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_default_levels");
$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'));
// render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_leveltable(0);
print $OUTPUT->footer();

View File

@ -1,48 +1,48 @@
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_config_skills");
$skill_id = required_param('skill_id', PARAM_INT);
$systemcontext = context_system::instance();
// Check if user has capability to manage skills
require_capability('block/gradelevel:skillmanager', $systemcontext);
$skill = block_gradelevel_levelset::find_by_id($skill_id);
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
print $OUTPUT->header();
// render skill editor
print $OUTPUT->heading(get_string('cfgpage_editskill','block_gradelevel')." ".$skill->getName());
print block_gradelevel_skillmgmtservice::render_skill_editor($skill_id);
// render level editor
print $OUTPUT->heading(get_string('cfgpage_skilllevels','block_gradelevel'));
print block_gradelevel_skillmgmtservice::render_leveltable($skill_id);
// add back button to return to skill management page
$cfg_skills_url = $CFG->wwwroot."/blocks/gradelevel/cfg_skills.php";
print "<button onclick='window.location=\"{$cfg_skills_url}\";'>".get_string('back','core')."</button>";
print $OUTPUT->footer();
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_config_skills");
$skill_id = required_param('skill_id', PARAM_INT);
$systemcontext = context_system::instance();
// Check if user has capability to manage skills
require_capability('block/gradelevel:skillmanager', $systemcontext);
$skill = block_gradelevel_levelset::find_by_id($skill_id);
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
print $OUTPUT->header();
// render skill editor
print $OUTPUT->heading(get_string('cfgpage_editskill','block_gradelevel')." ".$skill->getName());
print block_gradelevel_skillmgmtservice::render_skill_editor($skill_id);
// render level editor
print $OUTPUT->heading(get_string('cfgpage_skilllevels','block_gradelevel'));
print block_gradelevel_skillmgmtservice::render_leveltable($skill_id);
// add back button to return to skill management page
$cfg_skills_url = $CFG->wwwroot."/blocks/gradelevel/cfg_skills.php";
print "<button onclick='window.location=\"{$cfg_skills_url}\";'>".get_string('back','core')."</button>";
print $OUTPUT->footer();

View File

@ -1,35 +1,35 @@
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_config_skills");
$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/skilleditor', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
print $OUTPUT->header();
print $OUTPUT->heading(get_string('cfgpage_skills', 'block_gradelevel'));
// render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_skill_list(0);
print $OUTPUT->footer();
<?php
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
{
// If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php");
}
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_config_skills");
$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/skilleditor', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
print $OUTPUT->header();
print $OUTPUT->heading(get_string('cfgpage_skills', 'block_gradelevel'));
// render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_skill_list(0);
print $OUTPUT->footer();

View File

@ -1,492 +1,492 @@
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');
//namespace block_gradelevel;
class block_gradelevel_levelset {
const UNDEFINED_BADGE_COLOR="#3F3F3F";
const NULL_BADGE_COLOR = "#320000";
const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg";
const GLOBAL_DEFAULTS = array(
0 => "#320000",
250 => "#2ad4ff", // + 250
750 => "#cd7f32", // + 500
1750 => "#92A1A6", // + 1000
2750 => "#f6ae00", // + 2000
);
private $id;
private $data;
private $levels = null;
private $global_levels = null;
/**
* Construct a levelset object for an existing database item
*
*/
private function __construct($id = null, $dataObject = null)
{
global $DB;
$this->id = $id;
if($id != null)
{
if(isset($dataObject) && isset($dataObject->id) && $dataObject->id == $id) // slight sanity check
{
$this->data = $dataObject;
}
else {
// database validity check went south, retrieve again
$this->data = $DB->get_record('block_gradelevel_levelset', array('id' => $this->id));
}
//retrieve levels for this levelset
$this->levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $this->id));
usort( $this->levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
}
// retrieve global levels
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
usort( $this->global_levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
// if no global levels are defined, insert default global levels
if(count($this->global_levels) == 0)
{
foreach(static::GLOBAL_DEFAULTS as $points => $color)
{
// setup default
$row = new stdClass;
$row->levelset_id = 0;
$row->points = $points;
$row->badgecolor = $color;
// insert into db
if(!$DB->insert_record('block_gradelevel_levels',$row)){
print_error('inserterror', 'block_gradelevel');
}
}
// and reload global levels;
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
usort( $this->global_levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
}
}
public function getId() : string
{
return $this->id;
}
public function setName(string $name)
{
$this->data->name = $name;
}
public function getName() : string
{
return $this->data->name;
}
public function setIcon(string $iconname)
{
$this->data->icon = $iconname;
}
public function getIcon() : string
{
$icon = $this->data->icon;
if(empty($icon))
{
$icon = static::DEFAULT_ICON;
}
return $icon;
}
/**
* Find a levelset for a given course
*
* @params int $course_id The id of the course to find a levelset for
* @return levelset The levelset for this course or null if none found;
*/
static public function find_by_course($course_id)
{
global $DB;
try {
// FIXME: Make this more efficient by joining it into one sql statement.
$records = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
if(count($records) > 0)
{
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => array_values($records)[0]->levelset_id));
if($levelset)
{
return new static($levelset->id,$levelset);
}
}
}
catch(Exception $x){} // catch error if table does not (yet exist)
return null; // return null if no current levelset linked
}
static public function find_by_id(int $id)
{
global $DB;
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
if($levelset)
{
return new static($levelset->id,$levelset);
}
else
{
return null;
}
}
/**
* List attached courses for this levelset
*
* @return array An array with the id's of attached courses
*/
public function list_courses()
{
global $DB;
$list = array();
$links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $this->id));
foreach($links as $link)
{
$list[] = $link->course_id;
}
return $list;
}
/**
* Attach a course to this levelset. The course will be detached from any other levelsets.
*
* @params int $course_id The id of the course to attach
*/
public function attach_course($course_id)
{
global $DB;
// check if course attachement is already done
if(!in_array($course_id,$this->list_courses))
{
// no, now find an existing attachment for this course
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
if(empty($rows))
{
// create new attachment if existing link was not found
$row = new stdClass;
$row->levelset_id = $this->id;
$row->course_id = $course_id;
// insert new row
if(!$DB->insert_record('block_gradelevel_course_link',$row)){
print_error('inserterror', 'block_gradelevel');
}
}
else
{
// update existing link (automatically detaches course from its previous levelset)
$row = array_values($rows)[0];
$row->course_id = $course_id;
// update existing row
if(!$DB->update_record('block_gradelevel_course_link',$row)){
print_error('updateerror', 'block_gradelevel');
}
}
}
}
/**
* Detache a course from this levelset.
*
* @params int $course_id The id of the course to detach
*/
public function detach_course($course_id)
{
global $DB;
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id, 'levelset_id' => $this->id));
if(!empty($rows))
{
if(!$DB->delete_records('block_gradelevel_course_link', array('id' => array_values($rows)[0]->id)))
{
print_error('deleteerror','block_gradelevel');
}
}
}
/**
* Store changes made to the levelset data parameter containing levelset data
*
*/
public function save_data()
{
global $DB;
if($this->data->id == $this->id) // sanity check so we don't kill everything
{
if(!$DB->update_record('block_gradelevel_levelset',$this->data)){
print_error('updateerror', 'block_gradelevel');
}
}
else
{
print_error('datarowchanged_error', 'block_gradelevel');
}
}
/**
* Retrieve point total for all attached courses for a given user
*
* @param int $user_id The id
* @return int Total points for this user in this levelset
*/
public function get_levelset_grade($user_id)
{
// loop through all attached courses and add up the grade points gathered
$points = 0;
foreach($this->list_courses() as $course_id)
{
$result = grade_get_course_grade($user_id,$course_id);
$points += $result->grade;
}
return $points;
}
/**
* Return the levelup data for a given userid in this levelset
*
* @param int $user_id The id
* @return stdClass A stdClass containing the level data for the specified number of point
*/
public function get_user_leveldata($user_id)
{
$points = $this->get_levelset_grade($user_id);
return $this->calculate_level($points);
}
/**
* Create a new levelset
*
* @params string $name Optional name of the new levelset
* @return levelset The new levelset
*/
static public function create_new($name="New levelset")
{
global $DB;
// create a new levelset
$row = new stdClass;
$row->name = $name;
if(!$id = $DB->insert_record('block_gradelevel_levelset',$row, true)){
print_error('inserterror', 'block_gradelevel');
}
else
{
$rows = $DB->get_records('block_gradelevel_levelset', array('id' => $id));
if(count($rows) > 0)
{
return new static($id,array_values($rows)[0]);
}
}
throw new RuntimeException("Could not create new levelset");
}
/**
* List all levelsets
*
* @return array Array of levelset
*/
static public function list_all()
{
global $DB;
$list = array();
$levelsets = $DB->get_records('block_gradelevel_levelset');
foreach($levelsets as $lset)
{
$list[] = new static($lset->id,$lset);
}
return $list;
}
/**
* Calculate the levelup data, given a specified set of points
*
* @params int points The amount of points to calculate for
* @return stdClass A stdClass containing the level data for the specified number of point
*/
public function calculate_level($points){
$levels = $this->badgelevels();
$level = 0;
$badge_color = static::NULL_BADGE_COLOR;
$current_at = 0;
$next_at = 0;
foreach($levels as $threshold => $badgeColor)
{
if($points >= $threshold){
$level++;
$badge_color = $badgeColor;
$current_at = $threshold;
}
else
{
$next_at = $threshold;
break;
}
}
$levelup_points = $next_at - $current_at;
$points_in_level = $points - $current_at;
if($levelup_points == 0){ // at max level
$progress = 0;
$points_in_level = 0;
}
else
{
$progress = $points_in_level / $levelup_points;
}
$result = new stdClass;
$result->level = $level;
$result->badge_color = $badge_color;
$result->progress = $progress;
$result->next_at = $next_at;
$result->levelup_total = $levelup_points;
$result->points_in_level = $points_in_level;
return $result;
}
/**
* Simplified list of levels and associated badge colors for this levelset
* Takes data from global levelset if more specialized data is not set
*
* @return array An array of points (keys) and badge color (values), sorted by level
*/
public function badgelevels()
{
$level_info = array();
// If we have levels defined, use those, otherwise use the global levels
if(!empty($this->levels))
{
if(array_values($this->levels)[0]->points > 0)
{
// insert level 0
$level_info[0] = static::NULL_BADGE_COLOR;
}
$i = 0;
foreach($this->levels as $lvl)
{
// Check if color is properly set or needs to be retrieved from global config
if(!empty($lvl->badgecolor)) {
$color = $lvl->badgecolor;
}
else
{
$color = static::UNDEFINED_BADGE_COLOR;
}
$level_info[$lvl->points] = $color;
$i++;
}
}
else
{
if(empty($this->global_levels) || array_values($this->global_levels)[0]->points > 0)
{
// insert level 1 if levels don't start at 0 points,
// or if no global levels are defined. - At least start somewhere...
$level_info[0] = static::NULL_BADGE_COLOR;
}
// use global levels if levelset is not defined.
foreach($this->global_levels as $lvl)
{
// Check if color is properly set
if(!empty($lvl->badgecolor)) {
$color = $lvl->badgecolor;
}
else
{
$color = static::UNDEFINED_BADGE_COLOR;
}
$level_info[$lvl->points] = $color;
}
}
return $level_info;
}
public function render_badge(int $points,int $size=150){
global $CFG;
$info = $this->calculate_level($points);
$image = $this->getIcon();
if(strncmp($image,"data:",5) == 0)
{
$image_url = $CFG->wwwroot."/blocks/gradelevel/view-icon.php?skillid=".$this->id;
}
else
{
$image_url = $image;
}
$html = "<figure class='levelbadge weird'";
$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);
}
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');
//namespace block_gradelevel;
class block_gradelevel_levelset {
const UNDEFINED_BADGE_COLOR="#3F3F3F";
const NULL_BADGE_COLOR = "#320000";
const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg";
const GLOBAL_DEFAULTS = array(
0 => "#320000",
250 => "#2ad4ff", // + 250
750 => "#cd7f32", // + 500
1750 => "#92A1A6", // + 1000
2750 => "#f6ae00", // + 2000
);
private $id;
private $data;
private $levels = null;
private $global_levels = null;
/**
* Construct a levelset object for an existing database item
*
*/
private function __construct($id = null, $dataObject = null)
{
global $DB;
$this->id = $id;
if($id != null)
{
if(isset($dataObject) && isset($dataObject->id) && $dataObject->id == $id) // slight sanity check
{
$this->data = $dataObject;
}
else {
// database validity check went south, retrieve again
$this->data = $DB->get_record('block_gradelevel_levelset', array('id' => $this->id));
}
//retrieve levels for this levelset
$this->levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $this->id));
usort( $this->levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
}
// retrieve global levels
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
usort( $this->global_levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
// if no global levels are defined, insert default global levels
if(count($this->global_levels) == 0)
{
foreach(static::GLOBAL_DEFAULTS as $points => $color)
{
// setup default
$row = new stdClass;
$row->levelset_id = 0;
$row->points = $points;
$row->badgecolor = $color;
// insert into db
if(!$DB->insert_record('block_gradelevel_levels',$row)){
print_error('inserterror', 'block_gradelevel');
}
}
// and reload global levels;
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
usort( $this->global_levels, function( $a, $b) {
return ( $a->points < $b->points ) ? -1 : 1;
} );
}
}
public function getId() : string
{
return $this->id;
}
public function setName(string $name)
{
$this->data->name = $name;
}
public function getName() : string
{
return $this->data->name;
}
public function setIcon(string $iconname)
{
$this->data->icon = $iconname;
}
public function getIcon() : string
{
$icon = $this->data->icon;
if(empty($icon))
{
$icon = static::DEFAULT_ICON;
}
return $icon;
}
/**
* Find a levelset for a given course
*
* @params int $course_id The id of the course to find a levelset for
* @return levelset The levelset for this course or null if none found;
*/
static public function find_by_course($course_id)
{
global $DB;
try {
// FIXME: Make this more efficient by joining it into one sql statement.
$records = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
if(count($records) > 0)
{
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => array_values($records)[0]->levelset_id));
if($levelset)
{
return new static($levelset->id,$levelset);
}
}
}
catch(Exception $x){} // catch error if table does not (yet exist)
return null; // return null if no current levelset linked
}
static public function find_by_id(int $id)
{
global $DB;
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
if($levelset)
{
return new static($levelset->id,$levelset);
}
else
{
return null;
}
}
/**
* List attached courses for this levelset
*
* @return array An array with the id's of attached courses
*/
public function list_courses()
{
global $DB;
$list = array();
$links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $this->id));
foreach($links as $link)
{
$list[] = $link->course_id;
}
return $list;
}
/**
* Attach a course to this levelset. The course will be detached from any other levelsets.
*
* @params int $course_id The id of the course to attach
*/
public function attach_course($course_id)
{
global $DB;
// check if course attachement is already done
if(!in_array($course_id,$this->list_courses))
{
// no, now find an existing attachment for this course
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
if(empty($rows))
{
// create new attachment if existing link was not found
$row = new stdClass;
$row->levelset_id = $this->id;
$row->course_id = $course_id;
// insert new row
if(!$DB->insert_record('block_gradelevel_course_link',$row)){
print_error('inserterror', 'block_gradelevel');
}
}
else
{
// update existing link (automatically detaches course from its previous levelset)
$row = array_values($rows)[0];
$row->course_id = $course_id;
// update existing row
if(!$DB->update_record('block_gradelevel_course_link',$row)){
print_error('updateerror', 'block_gradelevel');
}
}
}
}
/**
* Detache a course from this levelset.
*
* @params int $course_id The id of the course to detach
*/
public function detach_course($course_id)
{
global $DB;
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id, 'levelset_id' => $this->id));
if(!empty($rows))
{
if(!$DB->delete_records('block_gradelevel_course_link', array('id' => array_values($rows)[0]->id)))
{
print_error('deleteerror','block_gradelevel');
}
}
}
/**
* Store changes made to the levelset data parameter containing levelset data
*
*/
public function save_data()
{
global $DB;
if($this->data->id == $this->id) // sanity check so we don't kill everything
{
if(!$DB->update_record('block_gradelevel_levelset',$this->data)){
print_error('updateerror', 'block_gradelevel');
}
}
else
{
print_error('datarowchanged_error', 'block_gradelevel');
}
}
/**
* Retrieve point total for all attached courses for a given user
*
* @param int $user_id The id
* @return int Total points for this user in this levelset
*/
public function get_levelset_grade($user_id)
{
// loop through all attached courses and add up the grade points gathered
$points = 0;
foreach($this->list_courses() as $course_id)
{
$result = grade_get_course_grade($user_id,$course_id);
$points += $result->grade;
}
return $points;
}
/**
* Return the levelup data for a given userid in this levelset
*
* @param int $user_id The id
* @return stdClass A stdClass containing the level data for the specified number of point
*/
public function get_user_leveldata($user_id)
{
$points = $this->get_levelset_grade($user_id);
return $this->calculate_level($points);
}
/**
* Create a new levelset
*
* @params string $name Optional name of the new levelset
* @return levelset The new levelset
*/
static public function create_new($name="New levelset")
{
global $DB;
// create a new levelset
$row = new stdClass;
$row->name = $name;
if(!$id = $DB->insert_record('block_gradelevel_levelset',$row, true)){
print_error('inserterror', 'block_gradelevel');
}
else
{
$rows = $DB->get_records('block_gradelevel_levelset', array('id' => $id));
if(count($rows) > 0)
{
return new static($id,array_values($rows)[0]);
}
}
throw new RuntimeException("Could not create new levelset");
}
/**
* List all levelsets
*
* @return array Array of levelset
*/
static public function list_all()
{
global $DB;
$list = array();
$levelsets = $DB->get_records('block_gradelevel_levelset');
foreach($levelsets as $lset)
{
$list[] = new static($lset->id,$lset);
}
return $list;
}
/**
* Calculate the levelup data, given a specified set of points
*
* @params int points The amount of points to calculate for
* @return stdClass A stdClass containing the level data for the specified number of point
*/
public function calculate_level($points){
$levels = $this->badgelevels();
$level = 0;
$badge_color = static::NULL_BADGE_COLOR;
$current_at = 0;
$next_at = 0;
foreach($levels as $threshold => $badgeColor)
{
if($points >= $threshold){
$level++;
$badge_color = $badgeColor;
$current_at = $threshold;
}
else
{
$next_at = $threshold;
break;
}
}
$levelup_points = $next_at - $current_at;
$points_in_level = $points - $current_at;
if($levelup_points == 0){ // at max level
$progress = 0;
$points_in_level = 0;
}
else
{
$progress = $points_in_level / $levelup_points;
}
$result = new stdClass;
$result->level = $level;
$result->badge_color = $badge_color;
$result->progress = $progress;
$result->next_at = $next_at;
$result->levelup_total = $levelup_points;
$result->points_in_level = $points_in_level;
return $result;
}
/**
* Simplified list of levels and associated badge colors for this levelset
* Takes data from global levelset if more specialized data is not set
*
* @return array An array of points (keys) and badge color (values), sorted by level
*/
public function badgelevels()
{
$level_info = array();
// If we have levels defined, use those, otherwise use the global levels
if(!empty($this->levels))
{
if(array_values($this->levels)[0]->points > 0)
{
// insert level 0
$level_info[0] = static::NULL_BADGE_COLOR;
}
$i = 0;
foreach($this->levels as $lvl)
{
// Check if color is properly set or needs to be retrieved from global config
if(!empty($lvl->badgecolor)) {
$color = $lvl->badgecolor;
}
else
{
$color = static::UNDEFINED_BADGE_COLOR;
}
$level_info[$lvl->points] = $color;
$i++;
}
}
else
{
if(empty($this->global_levels) || array_values($this->global_levels)[0]->points > 0)
{
// insert level 1 if levels don't start at 0 points,
// or if no global levels are defined. - At least start somewhere...
$level_info[0] = static::NULL_BADGE_COLOR;
}
// use global levels if levelset is not defined.
foreach($this->global_levels as $lvl)
{
// Check if color is properly set
if(!empty($lvl->badgecolor)) {
$color = $lvl->badgecolor;
}
else
{
$color = static::UNDEFINED_BADGE_COLOR;
}
$level_info[$lvl->points] = $color;
}
}
return $level_info;
}
public function render_badge(int $points,int $size=150){
global $CFG;
$info = $this->calculate_level($points);
$image = $this->getIcon();
if(strncmp($image,"data:",5) == 0)
{
$image_url = $CFG->wwwroot."/blocks/gradelevel/view-icon.php?skillid=".$this->id;
}
else
{
$image_url = $image;
}
$html = "<figure class='levelbadge weird'";
$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);
}
}

View File

@ -1,473 +1,473 @@
<?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;
}
<?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;
}
}

View File

@ -1,49 +1,49 @@
<?php
$capabilities = array(
'block/gradelevel:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/gradelevel:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'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
),
),
<?php
$capabilities = array(
'block/gradelevel:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/gradelevel:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'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
),
),
);

View File

@ -1,44 +1,44 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="blocks/gradelevel/db" VERSION="20180917" COMMENT="XMLDB file for Moodle blocks/gradelevel"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="block_gradelevel_levelset" COMMENT="Level set table">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="128" NOTNULL="false" SEQUENCE="false" COMMENT="Name of this level set"/>
<FIELD NAME="parent_id" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Optional parent for this level set (references another level set)"/>
<FIELD NAME="icon" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="parent_id_idx" TYPE="foreign" FIELDS="parent_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Parent index for nested levelsets"/>
</KEYS>
</TABLE>
<TABLE NAME="block_gradelevel_levels" COMMENT="Level references">
<FIELDS>
<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="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"/>
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Index for levelset reference"/>
</KEYS>
</TABLE>
<TABLE NAME="block_gradelevel_course_link" COMMENT="Link courses to level sets">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="course_id" TYPE="int" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="Id of the course to link"/>
<FIELD NAME="levelset_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the levelset a course links to"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="course_id_idx" TYPE="foreign-unique" FIELDS="course_id" REFTABLE="mdl_course" REFFIELDS="id" COMMENT="Course Id index"/>
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Levelset id reference"/>
</KEYS>
</TABLE>
</TABLES>
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="blocks/gradelevel/db" VERSION="20180917" COMMENT="XMLDB file for Moodle blocks/gradelevel"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="block_gradelevel_levelset" COMMENT="Level set table">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="128" NOTNULL="false" SEQUENCE="false" COMMENT="Name of this level set"/>
<FIELD NAME="parent_id" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Optional parent for this level set (references another level set)"/>
<FIELD NAME="icon" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="parent_id_idx" TYPE="foreign" FIELDS="parent_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Parent index for nested levelsets"/>
</KEYS>
</TABLE>
<TABLE NAME="block_gradelevel_levels" COMMENT="Level references">
<FIELDS>
<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="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"/>
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Index for levelset reference"/>
</KEYS>
</TABLE>
<TABLE NAME="block_gradelevel_course_link" COMMENT="Link courses to level sets">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="course_id" TYPE="int" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="Id of the course to link"/>
<FIELD NAME="levelset_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the levelset a course links to"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="course_id_idx" TYPE="foreign-unique" FIELDS="course_id" REFTABLE="mdl_course" REFFIELDS="id" COMMENT="Course Id index"/>
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Levelset id reference"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>

View File

@ -1,93 +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'),
),
);
<?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'),
),
);

View File

@ -1,70 +1,70 @@
<?php
function xmldb_block_gradelevel_upgrade($oldversion) {
global $DB;
$dbman = $DB->get_manager();
/// Add a new column newcol to the mdl_myqtype_options
if ($oldversion < 2018091600) {
// Define table block_gradelevel_levelset to be created.
$table = new xmldb_table('block_gradelevel_levelset');
// Adding fields to table block_gradelevel_levelset.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '128', null, null, null, null);
$table->add_field('parent_id', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
$table->add_field('icon', XMLDB_TYPE_TEXT, null, null, null, null, null);
// Adding keys to table block_gradelevel_levelset.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('parent_id_idx', XMLDB_KEY_FOREIGN, array('parent_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_levelset.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table block_gradelevel_levels to be created.
$table = new xmldb_table('block_gradelevel_levels');
// Adding fields to table block_gradelevel_levels.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('points', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('badgecolor', XMLDB_TYPE_CHAR, '10', null, null, null, null);
// Adding keys to table block_gradelevel_levels.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_levels.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table block_gradelevel_course_link to be created.
$table = new xmldb_table('block_gradelevel_course_link');
// Adding fields to table block_gradelevel_course_link.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('course_id', XMLDB_TYPE_INTEGER, '20', null, XMLDB_NOTNULL, null, null);
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table block_gradelevel_course_link.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('course_id_idx', XMLDB_KEY_FOREIGN_UNIQUE, array('course_id'), 'mdl_course', array('id'));
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_course_link.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Gradelevel savepoint reached.
upgrade_block_savepoint(true, 2018091600, 'gradelevel');
}
return true;
<?php
function xmldb_block_gradelevel_upgrade($oldversion) {
global $DB;
$dbman = $DB->get_manager();
/// Add a new column newcol to the mdl_myqtype_options
if ($oldversion < 2018091600) {
// Define table block_gradelevel_levelset to be created.
$table = new xmldb_table('block_gradelevel_levelset');
// Adding fields to table block_gradelevel_levelset.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '128', null, null, null, null);
$table->add_field('parent_id', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
$table->add_field('icon', XMLDB_TYPE_TEXT, null, null, null, null, null);
// Adding keys to table block_gradelevel_levelset.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('parent_id_idx', XMLDB_KEY_FOREIGN, array('parent_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_levelset.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table block_gradelevel_levels to be created.
$table = new xmldb_table('block_gradelevel_levels');
// Adding fields to table block_gradelevel_levels.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('points', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('badgecolor', XMLDB_TYPE_CHAR, '10', null, null, null, null);
// Adding keys to table block_gradelevel_levels.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_levels.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table block_gradelevel_course_link to be created.
$table = new xmldb_table('block_gradelevel_course_link');
// Adding fields to table block_gradelevel_course_link.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('course_id', XMLDB_TYPE_INTEGER, '20', null, XMLDB_NOTNULL, null, null);
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table block_gradelevel_course_link.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('course_id_idx', XMLDB_KEY_FOREIGN_UNIQUE, array('course_id'), 'mdl_course', array('id'));
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
// Conditionally launch create table for block_gradelevel_course_link.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Gradelevel savepoint reached.
upgrade_block_savepoint(true, 2018091600, 'gradelevel');
}
return true;
}

View File

@ -1,184 +1,184 @@
USER: stdClass Object
(
[id] => 2
[auth] => manual
[confirmed] => 1
[policyagreed] => 0
[deleted] => 0
[suspended] => 0
[mnethostid] => 1
[username] => admin
[idnumber] =>
[firstname] => Admin
[lastname] => User
[email] => pm@miqra.nl
[emailstop] => 0
[icq] =>
[skype] =>
[yahoo] =>
[aim] =>
[msn] =>
[phone1] =>
[phone2] =>
[institution] =>
[department] =>
[address] =>
[city] =>
[country] =>
[lang] => en
[calendartype] => gregorian
[theme] =>
[timezone] => 99
[firstaccess] => 1530717879
[lastaccess] => 1536959033
[lastlogin] => 1530732921
[currentlogin] => 1536953353
[lastip] => 2001:985:a081:1:5dfc:c799:21e1:4fdc
[secret] =>
[picture] => 0
[url] =>
[descriptionformat] => 1
[mailformat] => 1
[maildigest] => 0
[maildisplay] => 1
[autosubscribe] => 1
[trackforums] => 0
[timecreated] => 0
[timemodified] => 1530717931
[trustbitmask] => 0
[imagealt] =>
[lastnamephonetic] =>
[firstnamephonetic] =>
[middlename] =>
[alternatename] =>
[lastcourseaccess] => Array
(
[2] => 1530738819
)
[currentcourseaccess] => Array
(
[2] => 1536959033
)
[groupmember] => Array
(
)
[profile] => Array
(
)
[sesskey] => ejGT6VqIBv
[ajax_updatable_user_prefs] => Array
(
[drawer-open-nav] => alpha
[filepicker_recentrepository] => int
[filepicker_recentlicense] => safedir
[filepicker_recentviewmode] => int
[filemanager_recentviewmode] => int
)
[editing] => 1
[preference] => Array
(
[core_message_migrate_data] => 1
[auth_manual_passwordupdatetime] => 1530717931
[email_bounce_count] => 1
[email_send_count] => 1
[filepicker_recentrepository] => 4
[filepicker_recentlicense] => allrightsreserved
[login_failed_count_since_success] => 6
[ifirst] =>
[ilast] =>
[_lastloaded] => 1536959033
)
[enrol] => Array
(
[enrolled] => Array
(
[2] => 2147483647
)
[tempguest] => Array
(
)
)
[grade_last_report] => Array
(
[2] => grader
)
[gradeediting] => Array
(
[2] => 0
)
[access] => Array
(
[ra] => Array
(
[/1] => Array
(
[7] => 7
)
[/1/2] => Array
(
[8] => 8
)
[/1/40/23] => Array
(
[3] => 3
[5] => 5
)
)
[time] => 1536958657
[rsw] => Array
(
)
)
)
COURSE: stdClass Object
(
[id] => 2
[category] => 2
[sortorder] => 20001
[fullname] => PIC Microcontrollers programmeren
[shortname] => PIC-MCU3
[idnumber] =>
[summary] => Programmeren van PIC18 microcontrollers van microchip.
[summaryformat] => 1
[format] => topics
[showgrades] => 1
[newsitems] => 0
[startdate] => 1526594400
[enddate] => 0
[marker] => 0
[maxbytes] => 0
[legacyfiles] => 0
[showreports] => 0
[visible] => 1
[visibleold] => 1
[groupmode] => 0
[groupmodeforce] => 0
[defaultgroupingid] => 0
[lang] =>
[calendartype] =>
[theme] =>
[timecreated] => 1526555879
[timemodified] => 1536956992
[requested] => 0
[enablecompletion] => 1
[completionnotify] => 0
[cacherev] => 1536956992
)
USER: stdClass Object
(
[id] => 2
[auth] => manual
[confirmed] => 1
[policyagreed] => 0
[deleted] => 0
[suspended] => 0
[mnethostid] => 1
[username] => admin
[idnumber] =>
[firstname] => Admin
[lastname] => User
[email] => pm@miqra.nl
[emailstop] => 0
[icq] =>
[skype] =>
[yahoo] =>
[aim] =>
[msn] =>
[phone1] =>
[phone2] =>
[institution] =>
[department] =>
[address] =>
[city] =>
[country] =>
[lang] => en
[calendartype] => gregorian
[theme] =>
[timezone] => 99
[firstaccess] => 1530717879
[lastaccess] => 1536959033
[lastlogin] => 1530732921
[currentlogin] => 1536953353
[lastip] => 2001:985:a081:1:5dfc:c799:21e1:4fdc
[secret] =>
[picture] => 0
[url] =>
[descriptionformat] => 1
[mailformat] => 1
[maildigest] => 0
[maildisplay] => 1
[autosubscribe] => 1
[trackforums] => 0
[timecreated] => 0
[timemodified] => 1530717931
[trustbitmask] => 0
[imagealt] =>
[lastnamephonetic] =>
[firstnamephonetic] =>
[middlename] =>
[alternatename] =>
[lastcourseaccess] => Array
(
[2] => 1530738819
)
[currentcourseaccess] => Array
(
[2] => 1536959033
)
[groupmember] => Array
(
)
[profile] => Array
(
)
[sesskey] => ejGT6VqIBv
[ajax_updatable_user_prefs] => Array
(
[drawer-open-nav] => alpha
[filepicker_recentrepository] => int
[filepicker_recentlicense] => safedir
[filepicker_recentviewmode] => int
[filemanager_recentviewmode] => int
)
[editing] => 1
[preference] => Array
(
[core_message_migrate_data] => 1
[auth_manual_passwordupdatetime] => 1530717931
[email_bounce_count] => 1
[email_send_count] => 1
[filepicker_recentrepository] => 4
[filepicker_recentlicense] => allrightsreserved
[login_failed_count_since_success] => 6
[ifirst] =>
[ilast] =>
[_lastloaded] => 1536959033
)
[enrol] => Array
(
[enrolled] => Array
(
[2] => 2147483647
)
[tempguest] => Array
(
)
)
[grade_last_report] => Array
(
[2] => grader
)
[gradeediting] => Array
(
[2] => 0
)
[access] => Array
(
[ra] => Array
(
[/1] => Array
(
[7] => 7
)
[/1/2] => Array
(
[8] => 8
)
[/1/40/23] => Array
(
[3] => 3
[5] => 5
)
)
[time] => 1536958657
[rsw] => Array
(
)
)
)
COURSE: stdClass Object
(
[id] => 2
[category] => 2
[sortorder] => 20001
[fullname] => PIC Microcontrollers programmeren
[shortname] => PIC-MCU3
[idnumber] =>
[summary] => Programmeren van PIC18 microcontrollers van microchip.
[summaryformat] => 1
[format] => topics
[showgrades] => 1
[newsitems] => 0
[startdate] => 1526594400
[enddate] => 0
[marker] => 0
[maxbytes] => 0
[legacyfiles] => 0
[showreports] => 0
[visible] => 1
[visibleold] => 1
[groupmode] => 0
[groupmodeforce] => 0
[defaultgroupingid] => 0
[lang] =>
[calendartype] =>
[theme] =>
[timecreated] => 1526555879
[timemodified] => 1536956992
[requested] => 0
[enablecompletion] => 1
[completionnotify] => 0
[cacherev] => 1536956992
)

View File

@ -1,82 +1,82 @@
<?php
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
class block_gradelevel_edit_form extends block_edit_form {
protected function specific_definition($mform) {
global $CFG;
// retrieve levelset
$levelset = $this->block->levelset;
// Section header title according to language file.
$mform->addElement('header', 'config_header', get_string('blocksettings', 'block'));
$skills = block_gradelevel_levelset::list_all();
// sort by name
usort( $skills, function( $a, $b) {
return ( $a->getName() < $b->getName()) ? -1 : 1;
} );
$options = array( '-1' => get_string('edit_noneskill', 'block_gradelevel'));
foreach($skills as $skill)
{
$options[$skill->getId()] = $skill->getName();
}
// A sample string variable with a default value.
$mform->addElement('select', 'attached_skill', get_string('edit_pickskill', 'block_gradelevel'), $options);
}
public function set_data($defaults)
{
global $COURSE;
$defaults->attached_skill = -1;
// retrieve levelset
$skill = block_gradelevel_levelset::find_by_course($COURSE->id);
if(isset($skill)){
$defaults->attached_skill = $skill->getId();
}
parent::set_data($defaults);
}
public function get_data()
{
$data = parent::get_data();
if(isset($data))
{
$this->save_data($data);
}
return $data;
}
protected function save_data($data)
{
global $COURSE;
// retrieve levelset
if(isset($data->attached_skill))
{
$currentskill = block_gradelevel_levelset::find_by_course($COURSE->id);
if(isset($currentskill))
{
$currentskill->detach_course($COURSE->id);
}
$skill = block_gradelevel_levelset::find_by_id($data->attached_skill);
if(isset($skill)){
$skill->attach_course($COURSE->id);
}
}
}
<?php
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
class block_gradelevel_edit_form extends block_edit_form {
protected function specific_definition($mform) {
global $CFG;
// retrieve levelset
$levelset = $this->block->levelset;
// Section header title according to language file.
$mform->addElement('header', 'config_header', get_string('blocksettings', 'block'));
$skills = block_gradelevel_levelset::list_all();
// sort by name
usort( $skills, function( $a, $b) {
return ( $a->getName() < $b->getName()) ? -1 : 1;
} );
$options = array( '-1' => get_string('edit_noneskill', 'block_gradelevel'));
foreach($skills as $skill)
{
$options[$skill->getId()] = $skill->getName();
}
// A sample string variable with a default value.
$mform->addElement('select', 'attached_skill', get_string('edit_pickskill', 'block_gradelevel'), $options);
}
public function set_data($defaults)
{
global $COURSE;
$defaults->attached_skill = -1;
// retrieve levelset
$skill = block_gradelevel_levelset::find_by_course($COURSE->id);
if(isset($skill)){
$defaults->attached_skill = $skill->getId();
}
parent::set_data($defaults);
}
public function get_data()
{
$data = parent::get_data();
if(isset($data))
{
$this->save_data($data);
}
return $data;
}
protected function save_data($data)
{
global $COURSE;
// retrieve levelset
if(isset($data->attached_skill))
{
$currentskill = block_gradelevel_levelset::find_by_course($COURSE->id);
if(isset($currentskill))
{
$currentskill->detach_course($COURSE->id);
}
$skill = block_gradelevel_levelset::find_by_id($data->attached_skill);
if(isset($skill)){
$skill->attach_course($COURSE->id);
}
}
}
}

View File

@ -1,54 +1,54 @@
<?php
$string['pluginname'] = 'Grade Levelup';
$string['gradelevel'] = 'GradeLevel';
$string['title'] = 'Progress level';
$string['gradelevel:addinstance'] = 'Add a new Grade Level block';
$string['gradelevel:myaddinstance'] = 'Add a new Grade Level block to the My Moodle page';
$string['blockstring'] = 'Text in the block';
$string['levelup_at'] = 'Progress: ';
$string['levelup_done'] = 'Complete';
$string['unattached_course'] = 'Please attach this course to a skill in the block settings';
$string['teacher_view_results'] = 'View student results';
$string['edit_pickskill'] = "Attach to skill";
$string['edit_noneskill'] = "None";
$string['cfgpage_generic'] = "Grade Level settings";
$string['cfgpage_globallevels'] = "Default levels";
$string['cfgpage_skilllevels'] = "Edit levels";
$string['cfgpage_skills'] = "Manage skills";
$string['cfgpage_editskill'] = "Edit skill";
$string['results_heading'] = "Results for skill ";
$string['results_ungrouped'] = "Other";
$string['descconfig'] = "Configuration for Grade Level block";
$string['labeltitle'] = "Title of gradelevel block";
$string['desctitle'] = "The title of the gradelevel block in the courses";
$string['labelshowtitle'] = "Show title bar in block";
$string['descshowtitle'] = "Whether the block should show a title bar or not";
$string['labelnumlevels'] = "Number of deault levels";
$string['descnumlevels'] = "The number of levels that is set by default for all skills";
$string['levelcfg_description'] = "Levels will be sorted based on points. Make sure to set the points incrementally. Leave points empty to remove level";
$string['levelcfg_head_points'] = "Points";
$string['levelcfg_head_color'] = "Medal color";
$string['levelcfg_addlevel'] = "Add level";
$string['tooltip_editicon'] = "Edit icon";
$string['tooltip_editname'] = "Edit name";
$string['tooltip_deleteskill'] = "Delete skill";
$string['tooltip_deleteskill_disabled'] = "Cannot delete skill, because there are attached courses";
$string['defaults_name'] = "New skill";
$string['cfg_resetlevels'] = "Reset levels to default";
$string['cfg_addskill'] = "Add skill";
$string['title_confirmdelete'] = "Confirm delete";
$string['dialog_confirmdeleteskill'] = "Are you sure you want to delete this skill?";
//$string[''] = "";
<?php
$string['pluginname'] = 'Grade Levelup';
$string['gradelevel'] = 'GradeLevel';
$string['title'] = 'Progress level';
$string['gradelevel:addinstance'] = 'Add a new Grade Level block';
$string['gradelevel:myaddinstance'] = 'Add a new Grade Level block to the My Moodle page';
$string['blockstring'] = 'Text in the block';
$string['levelup_at'] = 'Progress: ';
$string['levelup_done'] = 'Complete';
$string['unattached_course'] = 'Please attach this course to a skill in the block settings';
$string['teacher_view_results'] = 'View student results';
$string['edit_pickskill'] = "Attach to skill";
$string['edit_noneskill'] = "None";
$string['cfgpage_generic'] = "Grade Level settings";
$string['cfgpage_globallevels'] = "Default levels";
$string['cfgpage_skilllevels'] = "Edit levels";
$string['cfgpage_skills'] = "Manage skills";
$string['cfgpage_editskill'] = "Edit skill";
$string['results_heading'] = "Results for skill ";
$string['results_ungrouped'] = "Other";
$string['descconfig'] = "Configuration for Grade Level block";
$string['labeltitle'] = "Title of gradelevel block";
$string['desctitle'] = "The title of the gradelevel block in the courses";
$string['labelshowtitle'] = "Show title bar in block";
$string['descshowtitle'] = "Whether the block should show a title bar or not";
$string['labelnumlevels'] = "Number of deault levels";
$string['descnumlevels'] = "The number of levels that is set by default for all skills";
$string['levelcfg_description'] = "Levels will be sorted based on points. Make sure to set the points incrementally. Leave points empty to remove level";
$string['levelcfg_head_points'] = "Points";
$string['levelcfg_head_color'] = "Medal color";
$string['levelcfg_addlevel'] = "Add level";
$string['tooltip_editicon'] = "Edit icon";
$string['tooltip_editname'] = "Edit name";
$string['tooltip_deleteskill'] = "Delete skill";
$string['tooltip_deleteskill_disabled'] = "Cannot delete skill, because there are attached courses";
$string['defaults_name'] = "New skill";
$string['cfg_resetlevels'] = "Reset levels to default";
$string['cfg_addskill'] = "Add skill";
$string['title_confirmdelete'] = "Confirm delete";
$string['dialog_confirmdeleteskill'] = "Are you sure you want to delete this skill?";
//$string[''] = "";

View File

@ -1,50 +1,50 @@
<?php
$string['pluginname'] = 'Cijferniveaus';
$string['gradelevel'] = 'GradeLevel';
$string['title'] = 'Voortgang Level';
$string['gradelevel:addinstance'] = 'Voeg een GradeLevel block toe';
$string['gradelevel:myaddinstance'] = 'Voeg een GradeLevel block aan mijn moodle toe';
$string['blockstring'] = 'Tekst in het blok';
$string['levelup_at'] = 'Voortgang: ';
$string['levelup_done'] = 'Klaar';
$string['unattached_course'] = 'Koppel deze cursus aan een skill in de eigenschappen van het blok.';
$string['teacher_view_results'] = 'Bekijk resultaten studenten';
$string['edit_pickskill'] = "Koppelen aan skill";
$string['edit_noneskill'] = "Geen";
$string['cfgpage_generic'] = "GradeLevel instellingen";
$string['cfgpage_globallevels'] = "Standaard levels";
$string['cfgpage_skilllevels'] = "Levels aanpassen";
$string['cfgpage_skills'] = "Skills beheren";
$string['cfgpage_editskill'] = "Skill aanpassen";
$string['results_heading'] = "Resultaten voor ";
$string['results_ungrouped'] = "Overig";
$string['descconfig'] = "Instellingen voor GradeLevel blok";
$string['labeltitle'] = "Titel van het gradelevel blok";
$string['desctitle'] = "De titel van het blok in de cursus";
$string['labelshowtitle'] = "Laat titelbalk in het blok zien";
$string['descshowtitle'] = "Geef aan of wel of niet de titel van het blok moet worden getoond";
$string['levelcfg_description'] = "Levels worden na opslaan gesorteerd op punten. Laat aantel punten leeg om een level te verwijderen";
$string['levelcfg_head_points'] = "Punten";
$string['levelcfg_head_color'] = "Badgekleur";
$string['levelcfg_addlevel'] = "Level toevoegen";
$string['tooltip_editicon'] = "Icoon aanpassen";
$string['tooltip_editname'] = "Naam aanpassen";
$string['tooltip_deleteskill'] = "Skill verwijderen";
$string['tooltip_deleteskill_disabled'] = "Skill kan niet worden verwijderd, omdat er cursussen aan gekoppeld zijn.";
$string['defaults_name'] = "Nieuwe skill";
$string['cfg_resetlevels'] = "Reset levels naar standaard";
$string['cfg_addskill'] = "Skill toevoegen";
$string['title_confirmdelete'] = "Bevestig verwijderen";
$string['dialog_confirmdeleteskill'] = "Week je zeker dat je deze skill witl verwijderen?";
//$string[''] = "";
<?php
$string['pluginname'] = 'Cijferniveaus';
$string['gradelevel'] = 'GradeLevel';
$string['title'] = 'Voortgang Level';
$string['gradelevel:addinstance'] = 'Voeg een GradeLevel block toe';
$string['gradelevel:myaddinstance'] = 'Voeg een GradeLevel block aan mijn moodle toe';
$string['blockstring'] = 'Tekst in het blok';
$string['levelup_at'] = 'Voortgang: ';
$string['levelup_done'] = 'Klaar';
$string['unattached_course'] = 'Koppel deze cursus aan een skill in de eigenschappen van het blok.';
$string['teacher_view_results'] = 'Bekijk resultaten studenten';
$string['edit_pickskill'] = "Koppelen aan skill";
$string['edit_noneskill'] = "Geen";
$string['cfgpage_generic'] = "GradeLevel instellingen";
$string['cfgpage_globallevels'] = "Standaard levels";
$string['cfgpage_skilllevels'] = "Levels aanpassen";
$string['cfgpage_skills'] = "Skills beheren";
$string['cfgpage_editskill'] = "Skill aanpassen";
$string['results_heading'] = "Resultaten voor ";
$string['results_ungrouped'] = "Overig";
$string['descconfig'] = "Instellingen voor GradeLevel blok";
$string['labeltitle'] = "Titel van het gradelevel blok";
$string['desctitle'] = "De titel van het blok in de cursus";
$string['labelshowtitle'] = "Laat titelbalk in het blok zien";
$string['descshowtitle'] = "Geef aan of wel of niet de titel van het blok moet worden getoond";
$string['levelcfg_description'] = "Levels worden na opslaan gesorteerd op punten. Laat aantel punten leeg om een level te verwijderen";
$string['levelcfg_head_points'] = "Punten";
$string['levelcfg_head_color'] = "Badgekleur";
$string['levelcfg_addlevel'] = "Level toevoegen";
$string['tooltip_editicon'] = "Icoon aanpassen";
$string['tooltip_editname'] = "Naam aanpassen";
$string['tooltip_deleteskill'] = "Skill verwijderen";
$string['tooltip_deleteskill_disabled'] = "Skill kan niet worden verwijderd, omdat er cursussen aan gekoppeld zijn.";
$string['defaults_name'] = "Nieuwe skill";
$string['cfg_resetlevels'] = "Reset levels naar standaard";
$string['cfg_addskill'] = "Skill toevoegen";
$string['title_confirmdelete'] = "Bevestig verwijderen";
$string['dialog_confirmdeleteskill'] = "Week je zeker dat je deze skill witl verwijderen?";
//$string[''] = "";

View File

@ -1,4 +1,4 @@
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');
<?php
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/querylib.php');

6
package-lock.json generated
View File

@ -1,3 +1,3 @@
{
"lockfileVersion": 1
}
{
"lockfileVersion": 1
}

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,40 +1,40 @@
<?php
$ADMIN->add('blocksettings', new admin_category('block_gradelevel', get_string('cfgpage_generic', 'block_gradelevel')));
$settings->add(new admin_setting_configcheckbox(
'gradelevel/showtitle',
get_string('labelshowtitle', 'block_gradelevel'),
get_string('descshowtitle', 'block_gradelevel'),
true
));
$settings->add(new admin_setting_configtext(
'gradelevel/blocktitle',
get_string('labeltitle', 'block_gradelevel'),
get_string('desctitle', 'block_gradelevel'),
get_string('title', 'block_gradelevel')
));
$ADMIN->add("block_gradelevel", $settings);
// Add the default levels page
$ADMIN->add("block_gradelevel", new admin_externalpage(
'block_gradelevel_default_levels',
get_string('cfgpage_globallevels', 'block_gradelevel'),
$CFG->wwwroot . '/blocks/gradelevel/cfg_globallevels.php'
)
);
// Add the skill configpage
$ADMIN->add("block_gradelevel", new admin_externalpage(
'block_gradelevel_config_skills',
get_string('cfgpage_skills', 'block_gradelevel'),
$CFG->wwwroot . '/blocks/gradelevel/cfg_skills.php'
)
);
<?php
$ADMIN->add('blocksettings', new admin_category('block_gradelevel', get_string('cfgpage_generic', 'block_gradelevel')));
$settings->add(new admin_setting_configcheckbox(
'gradelevel/showtitle',
get_string('labelshowtitle', 'block_gradelevel'),
get_string('descshowtitle', 'block_gradelevel'),
true
));
$settings->add(new admin_setting_configtext(
'gradelevel/blocktitle',
get_string('labeltitle', 'block_gradelevel'),
get_string('desctitle', 'block_gradelevel'),
get_string('title', 'block_gradelevel')
));
$ADMIN->add("block_gradelevel", $settings);
// Add the default levels page
$ADMIN->add("block_gradelevel", new admin_externalpage(
'block_gradelevel_default_levels',
get_string('cfgpage_globallevels', 'block_gradelevel'),
$CFG->wwwroot . '/blocks/gradelevel/cfg_globallevels.php'
)
);
// Add the skill configpage
$ADMIN->add("block_gradelevel", new admin_externalpage(
'block_gradelevel_config_skills',
get_string('cfgpage_skills', 'block_gradelevel'),
$CFG->wwwroot . '/blocks/gradelevel/cfg_skills.php'
)
);
$settings = null;

View File

@ -1,145 +1,145 @@
figure.levelbadge, figure.dummybadge {
text-align: center;
}
div.pointinfo {
text-align: center;
font-family: "Open Sans", Arial, helvetica, sans-serif;
}
div.pointinfo.complete {
font-weight: bold;
}
div.pointinfo span.currentpoints {
font-weight: bold;
}
div.pointinfo span.leveluppoints {
font-weight: bold;
}
div.teachermode {
text-align: center;
}
td.block_gradelevel_addlevel {
text-align: right;
}
input.jscolor[type=text] {
width: 5em;
}
div.skill_set ul {
padding-left: 0px;
margin-left: 0px;
}
div.skill_set li.skill_info {
position: relative; /* needed to have absolute positions be relative to this li */
list-style: none;
display: inline-block;
width: 220px;
height: 220px;
border-color: #ccc;
border-width: 1px;
border-style: solid;
margin: 5px;
padding: 5px;
padding-top: 10px;
}
div.skill_set li.skill_info figcaption {
text-align: center;
}
div.skill_set li.skill_info input[type=text] {
width: 150px;
}
div.skill_set li.skill_info a.editicon {
position: absolute;
top: 5px;
right: 10px;
}
div.skill_set li.skill_info a.deleteskill {
position: absolute;
top: 5px;
left: 7px;
}
div.skill_set li.skill_info a.deleteskill i.icon {
color: red;
}
div.skill_set li.skill_info a.deleteskill i.icon.disabled {
color: #ccc;
}
div.skill_set li.skill_info a.editname {
margin-left: 5px;
}
table.level_config tr[data-rowid='-255'] {
}
table.level_config tr[data-rowid='-255'] td {
}
table.level_config tr[data-rowid='-255'] input[data-name='points'] {
background-color: #F0F0F0;
}
div.block_gradelevel_results ul {
padding-left: 0px;
margin-left: 0px;
}
div .block_gradelevel_results li.result_badge {
position: relative; /* needed to have absolute positions be relative to this li */
list-style: none;
display: inline-block;
width: 190px;
height: 210px;
border-color: #ccc;
border-width: 1px;
border-style: solid;
margin: 5px;
padding: 5px;
padding-top: 10px;
}
div.block_gradelevel_results li.result_badge figcaption {
text-align: center;
height: 3em;
margin-bottom: 0.5rem;
}
div.block_gradelevel_results li.result_badge div.pointinfo {
font-size: 85%;
}
div.block_gradelevel_results li.result_badge figcaption span.namepart {
break-inside: avoid;
display: inline-block;
}
div.block_gradelevel_results figure.levelset_icon {
margin-bottom: 0.5rem;
}
figure.levelset_icon {
background-color: #ccc;
background-image: -moz-linear-gradient(45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(-45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(45deg, transparent 75%, #aaa 75%), -moz-linear-gradient(-45deg, transparent 75%, #aaa 75%);
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #aaa)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #aaa));
-moz-background-size: 32px 32px;
background-size: 32px 33px;
-webkit-background-size: 32px 33px; /* override value for shitty webkit */
background-position: 0 0, 16px 0, 16px -16px, 0px 16px;
display: inline-block;
figure.levelbadge, figure.dummybadge {
text-align: center;
}
div.pointinfo {
text-align: center;
font-family: "Open Sans", Arial, helvetica, sans-serif;
}
div.pointinfo.complete {
font-weight: bold;
}
div.pointinfo span.currentpoints {
font-weight: bold;
}
div.pointinfo span.leveluppoints {
font-weight: bold;
}
div.teachermode {
text-align: center;
}
td.block_gradelevel_addlevel {
text-align: right;
}
input.jscolor[type=text] {
width: 5em;
}
div.skill_set ul {
padding-left: 0px;
margin-left: 0px;
}
div.skill_set li.skill_info {
position: relative; /* needed to have absolute positions be relative to this li */
list-style: none;
display: inline-block;
width: 220px;
height: 220px;
border-color: #ccc;
border-width: 1px;
border-style: solid;
margin: 5px;
padding: 5px;
padding-top: 10px;
}
div.skill_set li.skill_info figcaption {
text-align: center;
}
div.skill_set li.skill_info input[type=text] {
width: 150px;
}
div.skill_set li.skill_info a.editicon {
position: absolute;
top: 5px;
right: 10px;
}
div.skill_set li.skill_info a.deleteskill {
position: absolute;
top: 5px;
left: 7px;
}
div.skill_set li.skill_info a.deleteskill i.icon {
color: red;
}
div.skill_set li.skill_info a.deleteskill i.icon.disabled {
color: #ccc;
}
div.skill_set li.skill_info a.editname {
margin-left: 5px;
}
table.level_config tr[data-rowid='-255'] {
}
table.level_config tr[data-rowid='-255'] td {
}
table.level_config tr[data-rowid='-255'] input[data-name='points'] {
background-color: #F0F0F0;
}
div.block_gradelevel_results ul {
padding-left: 0px;
margin-left: 0px;
}
div .block_gradelevel_results li.result_badge {
position: relative; /* needed to have absolute positions be relative to this li */
list-style: none;
display: inline-block;
width: 190px;
height: 210px;
border-color: #ccc;
border-width: 1px;
border-style: solid;
margin: 5px;
padding: 5px;
padding-top: 10px;
}
div.block_gradelevel_results li.result_badge figcaption {
text-align: center;
height: 3em;
margin-bottom: 0.5rem;
}
div.block_gradelevel_results li.result_badge div.pointinfo {
font-size: 85%;
}
div.block_gradelevel_results li.result_badge figcaption span.namepart {
break-inside: avoid;
display: inline-block;
}
div.block_gradelevel_results figure.levelset_icon {
margin-bottom: 0.5rem;
}
figure.levelset_icon {
background-color: #ccc;
background-image: -moz-linear-gradient(45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(-45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(45deg, transparent 75%, #aaa 75%), -moz-linear-gradient(-45deg, transparent 75%, #aaa 75%);
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #aaa)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #aaa));
-moz-background-size: 32px 32px;
background-size: 32px 33px;
-webkit-background-size: 32px 33px; /* override value for shitty webkit */
background-position: 0 0, 16px 0, 16px -16px, 0px 16px;
display: inline-block;
}

View File

@ -1,4 +1,4 @@
<?php
$plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
$plugin->version = 2018092402; // YYYYMMDDHH (year, month, day, 24-hr time)
<?php
$plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
$plugin->version = 2018112400; // YYYYMMDDHH (year, month, day, iteration)
$plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5)

View File

@ -1,49 +1,49 @@
<?php
//header("Content-type: image/svg+xml");
//ob_start();
require_once("../../config.php");
global $CFG;
global $DB;
$skillid = required_param('skillid', PARAM_INT);
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $skillid));
if(is_object($skill))
{
$image = $skill->icon;
if(strncmp($image,"data:",5) == 0)
{
$parts = explode(",",ltrim(substr($image,5)),2);
$typeinfo = explode(";",$parts[0]);
if(count($typeinfo) > 1 && $typeinfo[1] == "base64")
{
$binary = base64_decode($parts[1]);
}
else
{
$binary = $parts[0];
}
$mime = $typeinfo[0];
// set header
header("Content-type: {$mime}");
header("Pragma:");
// Allow cache for 5 seconds
header("Cache-Control: public, max-age=5");
// print data
print $binary;
}
else
{
// redirect to specified url
header("Location: {$image}",true,302);
}
}
else
{
http_response_code(404);
print "Image not found";
}
<?php
//header("Content-type: image/svg+xml");
//ob_start();
require_once("../../config.php");
global $CFG;
global $DB;
$skillid = required_param('skillid', PARAM_INT);
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $skillid));
if(is_object($skill))
{
$image = $skill->icon;
if(strncmp($image,"data:",5) == 0)
{
$parts = explode(",",ltrim(substr($image,5)),2);
$typeinfo = explode(";",$parts[0]);
if(count($typeinfo) > 1 && $typeinfo[1] == "base64")
{
$binary = base64_decode($parts[1]);
}
else
{
$binary = $parts[0];
}
$mime = $typeinfo[0];
// set header
header("Content-type: {$mime}");
header("Pragma:");
// Allow cache for 5 seconds
header("Cache-Control: public, max-age=5");
// print data
print $binary;
}
else
{
// redirect to specified url
header("Location: {$image}",true,302);
}
}
else
{
http_response_code(404);
print "Image not found";
}

View File

@ -1,90 +1,90 @@
<?php
require_once("../../config.php");
global $DB;
global $CFG;
const BADGE_SIZE = 100;
// Do sanity and access checks on course
$courseid = required_param('courseid', PARAM_INT);
$COURSE = get_course($courseid);
$coursecontext = context_course::instance($courseid);
$skill = block_gradelevel_levelset::find_by_course($courseid);
require_login($COURSE);
require_capability('block/gradelevel:viewresults', $coursecontext);
$PAGE->set_url('/blocks/gradelevel/view-results.php', array('courseid' => $courseid));
$PAGE->set_pagelayout('standard');
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
print $OUTPUT->header();
print $OUTPUT->heading(get_string('results_heading', 'block_gradelevel') . " " . $skill->getName());
print "<p>".get_string('course', 'core')." " . $COURSE->fullname."</p>";
//retrieve groups
$course_groups = groups_get_all_groups($COURSE->id);
// retrieve users
$remaining_users = get_enrolled_users($coursecontext);
print "<div class='block_gradelevel_results'>";
if(count($course_groups > 0))
{
// loop through all groups first
foreach($course_groups as $grp)
{
// Get members
$members = get_enrolled_users($coursecontext,'mod/assignment:submit',$grp->id);
$count_members = count($members);
// show group name
print $OUTPUT->heading($grp->name." ({$count_members})",4,array('groupname'));
// Sort on last name
usort( $members, function( $a, $b) {
return ( $a->lastname < $b->lastname ) ? -1 : 1;
} );
print "<ul class='skill_results'>";
foreach($members as $usr)
{
$pointstotal = $skill->get_levelset_grade($usr->id);
$level_info = $skill->calculate_level($pointstotal);
print "<li class='result_badge'>";
print $skill->render_badge($pointstotal,BADGE_SIZE);
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
print "</li>";
unset($remaining_users[$usr->id]);
}
print "</ul>";
}
$count_members = count($remaining_users);
print $OUTPUT->heading(get_string('results_ungrouped','block_gradelevel')." ({$count_members})" ,4,array('groupname'));
}
usort( $remaining_users, function( $a, $b) {
return ( $a->lastname < $b->lastname ) ? -1 : 1;
} );
print "<ul class='skill_results other'>";
foreach($remaining_users as $usr)
{
$pointstotal = $skill->get_levelset_grade($usr->id);
$level_info = $skill->calculate_level($pointstotal);
print "<li class='result_badge'>";
print $skill->render_badge($pointstotal,BADGE_SIZE);
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
print "</li>";
}
print "</ul>";
print "</div>";
print $OUTPUT->footer();
<?php
require_once("../../config.php");
global $DB;
global $CFG;
const BADGE_SIZE = 100;
// Do sanity and access checks on course
$courseid = required_param('courseid', PARAM_INT);
$COURSE = get_course($courseid);
$coursecontext = context_course::instance($courseid);
$skill = block_gradelevel_levelset::find_by_course($courseid);
require_login($COURSE);
require_capability('block/gradelevel:viewresults', $coursecontext);
$PAGE->set_url('/blocks/gradelevel/view-results.php', array('courseid' => $courseid));
$PAGE->set_pagelayout('standard');
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
print $OUTPUT->header();
print $OUTPUT->heading(get_string('results_heading', 'block_gradelevel') . " " . $skill->getName());
print "<p>".get_string('course', 'core')." " . $COURSE->fullname."</p>";
//retrieve groups
$course_groups = groups_get_all_groups($COURSE->id);
// retrieve users
$remaining_users = get_enrolled_users($coursecontext);
print "<div class='block_gradelevel_results'>";
if(count($course_groups > 0))
{
// loop through all groups first
foreach($course_groups as $grp)
{
// Get members
$members = get_enrolled_users($coursecontext,'mod/assignment:submit',$grp->id);
$count_members = count($members);
// show group name
print $OUTPUT->heading($grp->name." ({$count_members})",4,array('groupname'));
// Sort on last name
usort( $members, function( $a, $b) {
return ( $a->lastname < $b->lastname ) ? -1 : 1;
} );
print "<ul class='skill_results'>";
foreach($members as $usr)
{
$pointstotal = $skill->get_levelset_grade($usr->id);
$level_info = $skill->calculate_level($pointstotal);
print "<li class='result_badge'>";
print $skill->render_badge($pointstotal,BADGE_SIZE);
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
print "</li>";
unset($remaining_users[$usr->id]);
}
print "</ul>";
}
$count_members = count($remaining_users);
print $OUTPUT->heading(get_string('results_ungrouped','block_gradelevel')." ({$count_members})" ,4,array('groupname'));
}
usort( $remaining_users, function( $a, $b) {
return ( $a->lastname < $b->lastname ) ? -1 : 1;
} );
print "<ul class='skill_results other'>";
foreach($remaining_users as $usr)
{
$pointstotal = $skill->get_levelset_grade($usr->id);
$level_info = $skill->calculate_level($pointstotal);
print "<li class='result_badge'>";
print $skill->render_badge($pointstotal,BADGE_SIZE);
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
print "</li>";
}
print "</ul>";
print "</div>";
print $OUTPUT->footer();