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 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: 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 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. 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"); let debug = Debugger("renderbadge");
debug.enable(); 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 = { let self = {
init: function init() { init: function init() {
debug.info("Setting up badge renderers"); 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.y1,
(config.size ) * colors.radialGradient.r1 (config.size ) * colors.radialGradient.r1
); );
baseGradient.addColorStop(0, colors.lightPoint); baseGradient.addColorStop(0, hexToRgbA(colors.lightPoint));
baseGradient.addColorStop(1, colors.base); baseGradient.addColorStop(1, hexToRgbA(colors.base));
ctx.beginPath(); ctx.beginPath();
ctx.fillStyle = baseGradient; ctx.fillStyle = baseGradient;
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2, 0, 2 * Math.PI); 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 rflOffset = Math.asin(config.reflection.offset);
let rflAngleRad = (config.reflection.angle / 360.0) * 2 * Math.PI; let rflAngleRad = (config.reflection.angle / 360.0) * 2 * Math.PI;
debug.info("rflAngleRad:",rflAngleRad);
let rflGradient = ctx.createLinearGradient( let rflGradient = ctx.createLinearGradient(
(0.5 - config.reflection.offset * Math.sin(rflAngleRad))/2 * config.size, (0.5 - config.reflection.offset * Math.sin(rflAngleRad))/2 * config.size,
(0.5 + config.reflection.offset * Math.cos(rflAngleRad))/2 * config.size, (0.5 + config.reflection.offset * Math.cos(rflAngleRad))/2 * config.size,
Math.sin(rflAngleRad)/2 * config.size, Math.sin(rflAngleRad)/2 * config.size,
Math.cos(rflAngleRad)/2 * config.size Math.cos(rflAngleRad)/2 * config.size
); );
rflGradient.addColorStop(0, colors.reflection.lightest); debug.info("rflGradient",rflGradient);
rflGradient.addColorStop(1, colors.reflection.darkest); rflGradient.addColorStop(0, hexToRgbA(colors.reflection.lightest));
rflGradient.addColorStop(1, hexToRgbA(colors.reflection.darkest));
ctx.beginPath(); ctx.beginPath();
ctx.fillStyle = rflGradient; ctx.fillStyle = rflGradient;
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2, ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2,
0 + rflOffset + rflAngleRad, 0 + rflOffset + rflAngleRad,
Math.PI - rflOffset + rflAngleRad); Math.PI - rflOffset + rflAngleRad);
ctx.fill(); ctx.fill();
debug.info("Starting with border");
// draw empty border // draw empty border
let strokeWidth = config.size * config.borderWidth; let strokeWidth = config.size * config.borderWidth;
ctx.beginPath(); ctx.beginPath();

View File

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

View File

@ -1,34 +1,34 @@
<?php <?php
if(isset($_SERVER['SCRIPT_FILENAME'])) if(isset($_SERVER['SCRIPT_FILENAME']))
{ {
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly // 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']))); $root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
error_log("Using {$root}/config.php"); error_log("Using {$root}/config.php");
require_once($root."/config.php"); require_once($root."/config.php");
} }
else else
{ {
// If not, assume the cwd is not symlinked and proceed as we are used to // If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php"); require_once("../../config.php");
} }
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE? // HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_default_levels"); admin_externalpage_setup("block_gradelevel_default_levels");
$systemcontext = context_system::instance(); $systemcontext = context_system::instance();
// Check if user has capability to manage skills // Check if user has capability to manage skills
require_capability('block/gradelevel:skillmanager', $systemcontext); require_capability('block/gradelevel:skillmanager', $systemcontext);
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init'); $PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
print $OUTPUT->header(); print $OUTPUT->header();
print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel')); print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel'));
// render page for skill level 0 (global) // render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_leveltable(0); print block_gradelevel_skillmgmtservice::render_leveltable(0);
print $OUTPUT->footer(); print $OUTPUT->footer();

View File

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

View File

@ -1,35 +1,35 @@
<?php <?php
if(isset($_SERVER['SCRIPT_FILENAME'])) if(isset($_SERVER['SCRIPT_FILENAME']))
{ {
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly // 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']))); $root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
error_log("Using {$root}/config.php"); error_log("Using {$root}/config.php");
require_once($root."/config.php"); require_once($root."/config.php");
} }
else else
{ {
// If not, assume the cwd is not symlinked and proceed as we are used to // If not, assume the cwd is not symlinked and proceed as we are used to
require_once("../../config.php"); require_once("../../config.php");
} }
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE? // HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup("block_gradelevel_config_skills"); admin_externalpage_setup("block_gradelevel_config_skills");
$systemcontext = context_system::instance(); $systemcontext = context_system::instance();
// Check if user has capability to manage skills // Check if user has capability to manage skills
require_capability('block/gradelevel:skillmanager', $systemcontext); require_capability('block/gradelevel:skillmanager', $systemcontext);
$PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init'); $PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init');
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init'); $PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
print $OUTPUT->header(); print $OUTPUT->header();
print $OUTPUT->heading(get_string('cfgpage_skills', 'block_gradelevel')); print $OUTPUT->heading(get_string('cfgpage_skills', 'block_gradelevel'));
// render page for skill level 0 (global) // render page for skill level 0 (global)
print block_gradelevel_skillmgmtservice::render_skill_list(0); print block_gradelevel_skillmgmtservice::render_skill_list(0);
print $OUTPUT->footer(); print $OUTPUT->footer();

View File

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

View File

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

View File

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

View File

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

View File

@ -1,93 +1,93 @@
<?php <?php
$services = array( $services = array(
"Gradelevel Level Management" => array( "Gradelevel Level Management" => array(
'functions' => array('block_gradelevel_submit_levels', 'block_gradelevel_list_levels'), 'functions' => array('block_gradelevel_submit_levels', 'block_gradelevel_list_levels'),
'requiredcapability' => 'block/gradelevel:changelevels', 'requiredcapability' => 'block/gradelevel:changelevels',
'shortname'=> 'block_gradelevel_levelmgmt', 'shortname'=> 'block_gradelevel_levelmgmt',
'restrictedusers' => 0, 'restrictedusers' => 0,
'enabled' => 0, 'enabled' => 0,
'ajax' => true, 'ajax' => true,
), ),
); );
$functions = array( $functions = array(
'block_gradelevel_submit_levels' => array( //web service function name 'block_gradelevel_submit_levels' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'submit_levels', //external function name 'methodname' => 'submit_levels', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function '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 '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) 'type' => 'write', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_list_levels' => array( //web service function name 'block_gradelevel_list_levels' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'list_levels', //external function name 'methodname' => 'list_levels', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function '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 '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) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_list_skills' => array( //web service function name 'block_gradelevel_list_skills' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'list_skills', //external function name 'methodname' => 'list_skills', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
'description' => 'List skills', //human readable description of the web service function 'description' => 'List skills', //human readable description of the web service function
'type' => 'read', //database rights of the web service function (read, write) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_get_skill' => array( //web service function name 'block_gradelevel_get_skill' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'get_skill', //external function name 'methodname' => 'get_skill', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
'description' => 'Retrieve skill information', //human readable description of the web service function 'description' => 'Retrieve skill information', //human readable description of the web service function
'type' => 'read', //database rights of the web service function (read, write) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_update_skill' => array( //web service function name 'block_gradelevel_update_skill' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'update_skill', //external function name 'methodname' => 'update_skill', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
'description' => 'Update a skill', //human readable description of the web service function 'description' => 'Update a skill', //human readable description of the web service function
'type' => 'read', //database rights of the web service function (read, write) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_add_skill' => array( //web service function name 'block_gradelevel_add_skill' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'add_skill', //external function name 'methodname' => 'add_skill', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
'description' => 'Add a new skill', //human readable description of the web service 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) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
'block_gradelevel_delete_skill' => array( //web service function name 'block_gradelevel_delete_skill' => array( //web service function name
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
'methodname' => 'delete_skill', //external function name 'methodname' => 'delete_skill', //external function name
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
'description' => 'Delete a skill', //human readable description of the web service function 'description' => 'Delete a skill', //human readable description of the web service function
'type' => 'read', //database rights of the web service function (read, write) 'type' => 'read', //database rights of the web service function (read, write)
'ajax' => true, 'ajax' => true,
'capabilities' => 'block/gradelevel:skillmanager', 'capabilities' => 'block/gradelevel:skillmanager',
'loginrequired' => true, 'loginrequired' => true,
'services' => array('block_gradelevel_levelmgmt'), 'services' => array('block_gradelevel_levelmgmt'),
), ),
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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