From 6b165592013a2dca2536a736f5f6c41eecb2e5f2 Mon Sep 17 00:00:00 2001 From: pmk Date: Fri, 21 Sep 2018 22:30:09 +0200 Subject: [PATCH] Added web service for managing levelsets (now mostly called "skills") Default levels can be configured. Working on management interface for predefined skills. --- amd/src/leveleditor.js | 110 +++++++--- amd/src/renderbadge.js | 12 +- block_gradelevel.php | 32 +-- classes/levelset.php | 69 +++++- classes/skillmgmtservice.php | 406 +++++++++++++++++++++++++++++++++++ db/access.php | 23 ++ db/install.xml | 2 +- db/services.php | 93 ++++++++ doc_USER_GRADE.txt | 1 - edit_form.php | 4 +- globallevels.php | 63 +----- lang/en/block_gradelevel.php | 2 + styles.css | 3 + version.php | 2 +- 14 files changed, 704 insertions(+), 118 deletions(-) create mode 100644 classes/skillmgmtservice.php create mode 100644 db/services.php diff --git a/amd/src/leveleditor.js b/amd/src/leveleditor.js index 4f40792..0a72357 100644 --- a/amd/src/leveleditor.js +++ b/amd/src/leveleditor.js @@ -2,58 +2,116 @@ // You can call it anything you like define(['jquery', 'core/str', 'core/ajax', 'block_gradelevel/jscolor'], function ($, str, ajax, jscolor) { + let skill_id = null; + let $skill_table = null; + let self = { init: function init() { - $("input[type=number].uint").on('change', function (evt) { + + // Find skill table and skill id + $skill_table = $("table#level_config"); + skill_id = Number($skill_table.attr('data-skill')); + + if (!skill_id && skill_id !== 0 && skill_id !== '0') { + console.error("Cannot find configured skill id"); + return; + } + + // load and fill the level table + self.refresh(); + + // make sure all uint type numbers are not able to go below 0 + $(document).on('change', "input[type=number].uint", function (evt) { let $this = $(this); if ($this.val() < 0) { $this.val(0); } - }); + // On click handler for add level link $("a[data-action=addlevel]").on('click', function (evt) { - let $newtr = $("" - + "" - + ""); - - let $tbody = $("table#level_config tbody"); - - // apply jscolor to new row - $newtr.find("input.jscolor").each(function () { - let picker = new jscolor(this); - }); - // and add - $tbody.append($newtr); - - + self.add_levelrow(-255, '', '7F7F7F'); }); + // On click handler for save changes button $("button[data-action=savechanges]").on('click', self.submit); + + }, + add_levelrow: function (id, points, color) { + // create new row + let $newtr = $("" + + "" + + ""); + + // apply jscolor to new row + $newtr.find("input.jscolor").each(function () { + let picker = new jscolor(this); + }); + + // and add to the body of the table + $skill_table.find("tbody").append($newtr); + }, + refresh: function refresh() { + console.info("Attempting to refresh"); + + // perform refresh call + let promises = ajax.call([{ + methodname: 'block_gradelevel_list_levels', + args: { skill_id: skill_id }, + }]); + + // and link promise returns to callbacks + promises[0].done(self.success_refill_table).fail(self.fail_report_exception); }, submit: function submit(evt) { let $table = $("table#level_config"); - let data = { skill_id: $table.attr('data-skill'), levels: [] }; + let level_data = []; $table.find("tbody tr[data-rowid]").each(function () { let $this = $(this); let row = { - id: $this.attr('data-rowid'), + id: Number($this.attr('data-rowid')), points: $this.find("input[data-name=points]").val(), - color: $this.find("input[data-name=color]").val(), + badgecolor: $this.find("input[data-name=color]").val(), } - data.levels.push(row); + + if (row.points === "") { row.points = -255; } + row.points = Number(row.points); + + level_data.push(row); }); - console.info("Attempting to submit", data); + //console.info("Attempting to submit", level_data); - $.post("#", { action: "submitchanges", data: data }, function (result) { - console.info('result: ', result); - window.location.href = '#'; - }); + // perform ajax call + let promises = ajax.call([{ + methodname: 'block_gradelevel_submit_levels', + args: { skill_id: skill_id, levels: level_data }, + }]); - }, + // and link promise returns to callbacks + promises[0].done(self.success_refill_table).fail(self.fail_report_exception); + }, + success_refill_table: function success_refill_table(response) { + //console.info("Response from webservice: ", response); + let $tbody = $skill_table.find('tbody'); + $tbody.empty(); + for (let idx in response) { + let lvl = response[idx]; + //console.info("Level:", lvl); + self.add_levelrow(lvl.id, lvl.points, lvl.badgecolor); + } + }, + fail_report_exception: function fail_report_exception(ex) { + if (ex.error != undefined) { + console.error("Error from webservice: ", ex.error, "\n" , ex.debuginfo, "\n---Stack trace---\n", ex.stacktrace, "\n", ex); + } + else { + console.error("Exception from webservice: ", ex.message, "\n", ex.debuginfo, "\n---Stack trace---\n", ex.backtrace, "\n", ex); + } + + }, }; return self; diff --git a/amd/src/renderbadge.js b/amd/src/renderbadge.js index 856addf..74e511c 100644 --- a/amd/src/renderbadge.js +++ b/amd/src/renderbadge.js @@ -11,7 +11,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) { let props = self.fetchProperties(this); let $this = $(this); let $canvas = $(""); - console.info("$canvas", $canvas, $canvas[0]); + //console.info("$canvas", $canvas, $canvas[0]); $('canvas', this).remove();// clear out any existing canvas $this.append($canvas); // Put the canvas in there self.render($canvas[0], props); @@ -61,9 +61,9 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) { scale: 0.7, // scale to this fraction of image size } } - console.info("Config", config); - console.info("Colors", colors); - console.info("Props", props); + //console.info("Config", config); + //console.info("Colors", colors); + //console.info("Props", props); // draw main circle let baseGradient = ctx.createRadialGradient( @@ -159,7 +159,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) { ctx.drawImage(this, 15, 15, 120, 120);//imPos.x, imPos.y, imPos.w, imPos.h); } - console.info("Image: ",props.image); + //console.info("Image: ",props.image); iconImg.src = props.image; } @@ -177,7 +177,7 @@ define(['jquery', 'core/str', 'core/ajax'], function ($, str, ajax) { progress: $figure.attr("data-progress"), width: $figure.attr("data-width"), height: $figure.attr("data-height"), - color: $figure.attr("data-color"), + color: "#"+$figure.attr("data-color"), level: $figure.attr("data-level"), image: image, }; diff --git a/block_gradelevel.php b/block_gradelevel.php index 5a989a4..6cfd92c 100644 --- a/block_gradelevel.php +++ b/block_gradelevel.php @@ -44,6 +44,7 @@ class block_gradelevel extends block_base { public function get_content() { global $USER; + global $COURSE; if ($this->content !== null) { return $this->content; @@ -55,7 +56,7 @@ class block_gradelevel extends block_base { $pointstotal = $this->levelset->get_levelset_grade($USER->id); $level_info = $this->levelset->calculate_level($pointstotal); - $this->content->text = $this->render_badge($level_info->badge_color,$level_info->progress,$this->levelset->getIcon(),$level_info->level); + $this->content->text = $this->levelset->render_badge($pointstotal); if($level_info->levelup_total > 0) { @@ -66,38 +67,23 @@ class block_gradelevel extends block_base { $this->content->footer = "
".get_string('levelup_done','block_gradelevel')."
"; } - + $coursecontext = context_course::instance($COURSE->id); + + if(has_capability('block/gradelevel:viewresults', $coursecontext)) + { + $this->content->footer .= "\n"; + } return $this->content; } - public function hide_header() { return false; } + public function hide_header() { return !get_config('gradelevel', 'showtitle'); } public function has_config() { return true; } - - private function render_badge($basecolor,$progress,$image=null,$level="1"){ - global $CFG; - if(strncmp($image,"data: ",6) != 0) - { - $image_url = $CFG->wwwroot.$image; - } - else - { - $image_url = $image; - } - $html = "
"; - if(!empty($image)) - { - $html .= ""; - } - $html .= "
"; - return $html; - } - } \ No newline at end of file diff --git a/classes/levelset.php b/classes/levelset.php index a3d3b09..b1eae4f 100644 --- a/classes/levelset.php +++ b/classes/levelset.php @@ -10,11 +10,11 @@ class block_gradelevel_levelset { const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg"; const GLOBAL_DEFAULTS = array( - 0 => "#000000", - 25 => "#2ad4ff", - 50 => "#cd7f32", - 100 => "#a6a6a6", - 200 => "#f6ae00", + 0 => "#000000", + 250 => "#2ad4ff", // + 250 + 750 => "#cd7f32", // + 500 + 1750 => "#a6a6a6", // + 1000 + 2750 => "#f6ae00", // + 2000 ); private $id; @@ -85,6 +85,11 @@ class block_gradelevel_levelset { } + public function getId() : string + { + return $this->id; + } + public function setName(string $name) { $this->data->name = $name; @@ -136,6 +141,19 @@ class block_gradelevel_levelset { return null; // return null if no current levelset linked } + static public function find_by_id($id) + { + $levelset = $DB->get_record('block_gradelevel_levelset', array('id' => array_values($records)[0]->levelset_id)); + if($levelset) + { + return new static($levelset->id,$levelset); + } + else + { + return null; + } + + } /** * List attached courses for this levelset @@ -190,8 +208,6 @@ class block_gradelevel_levelset { print_error('updateerror', 'block_gradelevel'); } } - - } } @@ -436,4 +452,43 @@ class block_gradelevel_levelset { } + public function render_badge(int $points,int $size=150){ + global $CFG; + + $info = $this->calculate_level($points); + + $image = $this->getIcon(); + if(strncmp($image,"data: ",6) != 0) + { + $image_url = $CFG->wwwroot.$image; + } + else + { + $image_url = $image; + } + + $html = "
badgelevels(); + $maxpoints = array_pop(array_keys($levels)); + + return $this->render_badge($maxpoints,$size); + + } + } \ No newline at end of file diff --git a/classes/skillmgmtservice.php b/classes/skillmgmtservice.php new file mode 100644 index 0000000..882b3c6 --- /dev/null +++ b/classes/skillmgmtservice.php @@ -0,0 +1,406 @@ +libdir.'/gradelib.php'); +require_once($CFG->libdir.'/externallib.php'); +require_once($CFG->dirroot.'/grade/querylib.php'); + +//namespace block_gradelevel; + + +class block_gradelevel_skillmgmtservice extends external_api +{ + const DEBUG = false; // enable debug logging + const DEMOBADGE_SIZE = 100; // size of demo badge + + private static function log($message) + { + if(self::DEBUG) + { + error_log($message."\n",3,"/tmp/block_gradelevel.log"); + } + } + + private static function list_courses($skill_id) + { + global $DB; + $list = array(); + $links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $skill_id)); + foreach($links as $link) + { + $list[] = $link->course_id; + } + + return $list; + } + + // Input parameter config + public static function submit_levels_parameters() + { + return new external_function_parameters( + array( + 'skill_id' => new external_value(PARAM_INT, 'id of skill'), + 'levels' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'id of level'), + 'points' => new external_value(PARAM_INT, 'number of points for this level'), + 'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'), + ) + ) + ) + ) + ); + } + + public static function list_levels_parameters() + { + return new external_function_parameters( + array( + 'skill_id' => new external_value(PARAM_INT, 'id of skill'), + ) + ); + } + + public static function list_skills_parameters() + { + return new external_function_parameters( array() ); + } + + public static function get_skill_parameters() + { + return new external_function_parameters( + array( + 'id' => new external_value(PARAM_INT, 'id of skill'), + ) + ); + } + + public static function update_skill_parameters() + { + return new external_function_parameters( + array( + 'id' => new external_value(PARAM_INT, 'id of skill'), + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + ) + ); + } + + public static function add_skill_parameters() + { + return new external_function_parameters( + array( + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + ) + ); + } + + public static function delete_skill_parameters() + { + return new external_function_parameters( + array( + 'id' => new external_value(PARAM_INT, 'Id of skill'), + ) + ); + } + + // Output parameter config + public static function submit_levels_returns() + { + return new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'id of level'), + 'points' => new external_value(PARAM_INT, 'number of points for this level'), + 'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'), + ) + ) + ); + } + + public static function list_levels_returns() + { + return new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'id of level'), + 'points' => new external_value(PARAM_INT, 'number of points for this level'), + 'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'), + ) + ) + ); + } + + public static function list_skills_returns() + { + return new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Id of skill'), + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + 'html' => new external_value(PARAM_RAW, 'Demo badge'), + ) + ) + ); + } + + public static function get_skill_returns() + { + return new external_single_structure( + array( + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + 'html' => new external_value(PARAM_RAW, 'Demo badge'), + ) + ); + } + + public static function update_skill_returns() + { + return new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Id of skill'), + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + 'html' => new external_value(PARAM_RAW, 'Demo badge'), + ) + ); + } + + public static function add_skill_returns() + { + return new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Id of skill'), + 'name' => new external_value(PARAM_TEXT, 'Name of skill'), + 'icon' => new external_value(PARAM_RAW, 'Icon for skill'), + 'html' => new external_value(PARAM_RAW, 'Demo badge'), + ) + ); + } + + public static function delete_skill_returns() + { + return new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Id of skill'), + 'deleted' => new external_value(PARAM_BOOL, 'Deletion succesful'), + ) + ); + } + + // Actual functions + public static function submit_levels(int $skill_id, array $levels) + { + global $CFG, $DB; + self::log("submit_levels called, skill_id: {$skill_id}, levels: \n".print_r($levels,true)); + + $systemcontext = context_system::instance(); + self::validate_context($systemcontext); + + if(skill_id == 0) + { + // Check if user has capability to manage global levels + require_capability('block/gradelevel:managelevels', $systemcontext); + } + else + { + // Check if user has teacher or manager capability in any of the attached courses + $capability = false; + $courses = self::list_courses($skill_id); + foreach($courses as $course_id) + { + $coursecontext = context_course::instance($course_id); + $capability |= has_capability('block/gradelevel:changelevels', $coursecontext); + } + + if(!$capability) + { + throw new Exception("Access denied - you do not have editing capabilities for one of the attached courses"); + } + } + + + foreach($levels as $lvl_raw) + { + // convert level array to stdObj + $lvl = (object) $lvl_raw; + $lvl->levelset_id = $skill_id; + + self::log("Processing level: ".print_r($lvl,true)); + + if($lvl->points >= 0) + { + if($lvl->id >= 0) + { + // Update record + self::log("updating row {$lvl->id}: {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}"); + $DB->update_record('block_gradelevel_levels',$lvl); + } + else + { + // unset invalid id before insert + unset($lvl->id); + self::log("inserting new row {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}"); + // Insert record + $DB->insert_record('block_gradelevel_levels',$lvl); + } + } + else + { + // points is empty: delete record if we have a valid id. + if($lvl->id >= 0) + { + self::log("deleting empty row {$lvl->id}"); + $DB->delete_records('block_gradelevel_levels', array('id' => $lvl->id)); + } + else + { + self::log("ignoring empty row"); + } + + }/**/ + + } + + return static::list_levels($skill_id); + } + + public static function list_levels(int $skill_id) + { + global $CFG, $DB; + + $levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $skill_id)); + + // Sort by points + usort( $levels, function( $a, $b) { + return ( $a->points < $b->points ) ? -1 : 1; + } ); + + + return $levels; + + } + + public static function list_skills() + { + global $CFG, $DB; + + $skills = $DB->get_records('block_gradelevel_levelset'); + + // Sort by points + usort( $skills, function( $a, $b) { + return ( $a->name < $b->name) ? -1 : 1; + } ); + + foreach($skills as $skill ) + { + $skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE); + } + + + return $skills; + + + } + + public static function get_skill(int $id) + { + global $CFG, $DB; + + $skill = $DB->get_record('block_gradelevel_levels', array('id' => $id)); + $skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE); + + return $skill; + + } + + public static function update_skill(int $id, string $name, string $icon ) + { + global $CFG, $DB; + + $skill = $DB->get_record('block_gradelevel_levelset', array('id' => $id)); + + $skill->name = $name; + $skill->icon = $icon; + + $DB->update_record('block_gradelevel_levelset',$skill); + + $skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE); + + return $skill; + } + + public static function add_skill(string $name, string $icon) + { + global $CFG, $DB; + + $skill = stdObj; + + $skill->name = $name; + $skill->icon = $icon; + + $id = $DB->insert_record('block_gradelevel_levelset',$skill, true); + + $skill->id = $id; + $skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE); + + return $skill; + } + + public static function delete_skill(int $id) + { + global $CFG, $DB; + + $result = stdObj; + $result->id = $id; + + $result->id = ($DB->delete_record('block_gradelevel_levelset',array('id' => $id)))?true:false; + return $result; + } + + + // Other public functions + + public static function render_leveltable($skill_id) + { + $levels = static::list_levels($skill_id); + + $s = "

".get_string('levelcfg_description','block_gradelevel')."

"; + $s .= ""; + $s .= ""; + $s .= ""; + foreach($levels as $lvl) + { + $color = ltrim($lvl->badgecolor,"#"); // trim any leading hashes + $s .= ""; + + } + $s .= ""; + $s .= ""; + $s .= "
".get_string('levelcfg_head_points','block_gradelevel')."".get_string('levelcfg_head_color','block_gradelevel')."
".get_string("levelcfg_addlevel",'block_gradelevel')."
"; + $s .= "

"; + + return $s; + + } + + public static function render_skill_list() + { + $skills = block_gradelevel_levelset::list_all(); + + $s = "
    "; + foreach($skills as $skill) + { + $skill_id = $skill->getId(); + $s .= "
  • ".$skill->render_demo_badge(DEMOBADGE_SIZE); + $s .= "
    ".$skill->getName()."
    "; + $s .= "
  • "; + } + + $s .= "
"; + + } + +} \ No newline at end of file diff --git a/db/access.php b/db/access.php index 2c212ad..f93e569 100644 --- a/db/access.php +++ b/db/access.php @@ -23,4 +23,27 @@ 'clonepermissionsfrom' => 'moodle/site:manageblocks' ), + + 'block/gradelevel:skillmanager' => array( + 'riskbitmask' => RISK_CONFIG | RISK_DATALOSS | RISK_XSS, + + 'captype' => 'write', + 'contextlevel' => CONTEXT_SYSTEM, + 'archetypes' => array( + 'manager' => CAP_ALLOW + ), + ), + + 'block/gradelevel:viewresults' => array( + 'riskbitmask' => RISK_DATALOSS | RISK_XSS, + + 'captype' => 'write', + 'contextlevel' => CONTEXT_BLOCK, + 'archetypes' => array( + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW + ), + + ), + ); \ No newline at end of file diff --git a/db/install.xml b/db/install.xml index 609c00f..8924ab4 100644 --- a/db/install.xml +++ b/db/install.xml @@ -21,7 +21,7 @@ - + diff --git a/db/services.php b/db/services.php new file mode 100644 index 0000000..b9cdef4 --- /dev/null +++ b/db/services.php @@ -0,0 +1,93 @@ + array( + 'functions' => array('block_gradelevel_submit_levels', 'block_gradelevel_list_levels'), + 'requiredcapability' => 'block/gradelevel:changelevels', + 'shortname'=> 'block_gradelevel_levelmgmt', + 'restrictedusers' => 0, + 'enabled' => 0, + 'ajax' => true, + ), +); + +$functions = array( + 'block_gradelevel_submit_levels' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'submit_levels', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'Update level settings for a given skill', //human readable description of the web service function + 'type' => 'write', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_list_levels' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'list_levels', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'List level settings for a given skill', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_list_skills' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'list_skills', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'List skills', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_get_skill' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'get_skill', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'Retrieve skill information', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_update_skill' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'update_skill', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'Update a skill', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_add_skill' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'add_skill', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'Add a new skill', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + 'block_gradelevel_delete_skill' => array( //web service function name + 'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function + 'methodname' => 'delete_skill', //external function name + 'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function + 'description' => 'Delete a skill', //human readable description of the web service function + 'type' => 'read', //database rights of the web service function (read, write) + 'ajax' => true, + 'capabilities' => 'block/gradelevel:skillmanager', + 'loginrequired' => true, + 'services' => array('block_gradelevel_levelmgmt'), + ), + +); diff --git a/doc_USER_GRADE.txt b/doc_USER_GRADE.txt index e403f87..1877541 100644 --- a/doc_USER_GRADE.txt +++ b/doc_USER_GRADE.txt @@ -157,7 +157,6 @@ COURSE: stdClass Object [shortname] => PIC-MCU3 [idnumber] => [summary] => Programmeren van PIC18 microcontrollers van microchip. - [summaryformat] => 1 [format] => topics [showgrades] => 1 diff --git a/edit_form.php b/edit_form.php index a6f3723..ab7013e 100644 --- a/edit_form.php +++ b/edit_form.php @@ -29,7 +29,9 @@ class block_gradelevel_edit_form extends block_edit_form { $mform->addElement('filepicker', 'levelset_icon', get_string('levelset_icon_new', 'block_gradelevel'), null, array('maxbytes' => $maxbytes, 'accepted_types' => array('.png', '.svg'))); - + $mform->addElement('header', 'config_header', get_string('levelset_levels', 'block_gradelevel')); + $mform->addElement('html',print block_gradelevel_managelevelservice::render_leveltable(0)); + } public function set_data($defaults) diff --git a/globallevels.php b/globallevels.php index 2238189..8a72895 100644 --- a/globallevels.php +++ b/globallevels.php @@ -3,6 +3,7 @@ if(isset($_SERVER['SCRIPT_FILENAME'])) { // If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly $root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME']))); + error_log("Using {$root}/config.php"); require_once($root."/config.php"); } else @@ -15,61 +16,19 @@ else require_once($CFG->libdir.'/adminlib.php'); + admin_externalpage_setup("block_gradelevel_default_levels"); -$action = optional_param('action', null, PARAM_ALPHA); -$data = optional_param('data', null, PARAM_ALPHA); -if(!empty($data)) -{ - $data = json_decode($data); -} - -if(!empty($action) && confirm_sesskey()) -{ - switch($action) { - case 'submitchanges': - - print_r($data); +$systemcontext = context_system::instance(); +// Check if user has capability to manage skills +require_capability('block/gradelevel:skillmanager', $systemcontext); +$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init'); +print $OUTPUT->header(); +print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel')); - - - redirect($PAGE->url); - break; - } - -} -else -{ - $PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init'); - - print $OUTPUT->header(); - print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel')); - - $global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0)); - usort( $global_levels, function( $a, $b) { - return ( $a->points < $b->points ) ? -1 : 1; - } ); - - $skill_id = 0; - print "

".get_string('levelcfg_description','block_gradelevel')."

"; - print ""; - print ""; - print ""; - foreach($global_levels as $lvl) - { - $color = ltrim($lvl->badgecolor,"#"); - print ""; - - } - print ""; - print ""; - print "
".get_string('levelcfg_head_points','block_gradelevel')."".get_string('levelcfg_head_color','block_gradelevel')."
".get_string("levelcfg_addlevel",'block_gradelevel')."
"; - print "

"; - - - - print $OUTPUT->footer(); -} \ No newline at end of file +// render page for skill level 0 (global) +print block_gradelevel_skillmgmtservice::render_leveltable(0); +print $OUTPUT->footer(); diff --git a/lang/en/block_gradelevel.php b/lang/en/block_gradelevel.php index afb4004..8fcb711 100644 --- a/lang/en/block_gradelevel.php +++ b/lang/en/block_gradelevel.php @@ -8,6 +8,8 @@ $string['blockstring'] = 'Text in the block'; $string['levelup_at'] = 'Next level: '; $string['levelup_done'] = 'Complete'; +$string['teacher_view_results'] = 'View student results'; + $string['levelset_name'] = "Skill name"; $string['levelset_icon_cur'] = "Current skill icon (for level badge)"; $string['levelset_icon_new'] = "New skill icon (for level badge)"; diff --git a/styles.css b/styles.css index 8388d08..164f933 100644 --- a/styles.css +++ b/styles.css @@ -17,6 +17,9 @@ div.pointinfo { div.pointinfo span.leveluppoints { font-weight: bold; } +div.teachermode { + text-align: center; +} td.block_gradelevel_addlevel { text-align: right; diff --git a/version.php b/version.php index 0133c93..c9215c8 100644 --- a/version.php +++ b/version.php @@ -1,4 +1,4 @@ component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494) -$plugin->version = 2018091600; // YYYYMMDDHH (year, month, day, 24-hr time) +$plugin->version = 2018092101; // YYYYMMDDHH (year, month, day, 24-hr time) $plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5) \ No newline at end of file