Skip to content
Snippets Groups Projects
Commit cc69a7d4 authored by Yoshi5123's avatar Yoshi5123
Browse files

Merging with planification

parents 94c9380b 42271d07
No related branches found
No related tags found
No related merge requests found
Showing
with 3231 additions and 320 deletions
...@@ -27,11 +27,16 @@ define('AJAX_SCRIPT', true); ...@@ -27,11 +27,16 @@ define('AJAX_SCRIPT', true);
require_once(dirname(__FILE__) . '/../../config.php'); require_once(dirname(__FILE__) . '/../../config.php');
require_once(dirname(__FILE__) . '/locallib.php'); require_once(dirname(__FILE__) . '/locallib.php');
<<<<<<< HEAD
global $USER, $COURSE, $DB; global $USER, $COURSE, $DB;
=======
global $USER, $COURSE, $DB;
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
$userid = required_param('userid', PARAM_INT);
$courseid = required_param('courseid', PARAM_INT); $courseid = required_param('courseid', PARAM_INT);
$userid = required_param('userid', PARAM_INT);
$COURSE = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $COURSE = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$USER = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); $USER = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
...@@ -39,8 +44,8 @@ $USER = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST); ...@@ -39,8 +44,8 @@ $USER = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
require_login($COURSE, false); require_login($COURSE, false);
$context = context_course::instance($courseid); $context = context_course::instance($courseid);
require_capability('local/notemyprogress:ajax', $context); require_capability('local/notemyprogress:ajax', $context);
/* Start the déclaration of all the optional parrameters */
$beginDate = optional_param('beginDate', false, PARAM_TEXT); $beginDate = optional_param('beginDate', false, PARAM_TEXT); //optional_param('keyValue','DefaultValue','Type value');
$lastDate = optional_param('lastDate', false, PARAM_TEXT); $lastDate = optional_param('lastDate', false, PARAM_TEXT);
$sectionname = optional_param('sectionname', false, PARAM_TEXT); $sectionname = optional_param('sectionname', false, PARAM_TEXT);
...@@ -83,20 +88,39 @@ $modulename = optional_param('modulename', false, PARAM_TEXT); ...@@ -83,20 +88,39 @@ $modulename = optional_param('modulename', false, PARAM_TEXT);
$newinstance = optional_param('newinstance', false, PARAM_BOOL); $newinstance = optional_param('newinstance', false, PARAM_BOOL);
//gamification parameters
$rules = optional_param('rules', false ,PARAM_TEXT);
$levels = optional_param('levels', false ,PARAM_TEXT);
$settings= optional_param('settings', false ,PARAM_TEXT);
$url= optional_param('url', false ,PARAM_TEXT);
//$courseid = optional_param('modulename', false ,PARAM_TEXT);
$enable = optional_param('enable', false ,PARAM_BOOL);
$section = optional_param('section',false,PARAM_TEXT);
$params = array(); /* */
$func = null;
<<<<<<< HEAD
//debug_text::print("Enter ajax file"); //debug_text::print("Enter ajax file");
if ($action == 'saveconfigweek') { if ($action == 'saveconfigweek') {
=======
$params = array(); // Array containing the data
$func = null; // fuction which will be call at line 193
if($action == 'saveconfigweek') {//Exemple: if the action passed is saveconfigweek then my array contain (weeks,courseid,userid,newinstance)
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
array_push($params, $weeks); array_push($params, $weeks);
array_push($params, $courseid); array_push($params, $courseid);
array_push($params, $userid); array_push($params, $userid);
array_push($params, $newinstance); array_push($params, $newinstance);
<<<<<<< HEAD
if ($weeks && $courseid && $userid) { if ($weeks && $courseid && $userid) {
$func = "local_notemyprogress_save_weeks_config"; $func = "local_notemyprogress_save_weeks_config";
=======
if($weeks && $courseid && $userid){
$func = "local_notemyprogress_save_weeks_config"; //this function must be contained in localib.php
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
} }
} elseif ($action == 'changegroup') { } elseif ($action == 'changegroup') {
array_push($params, $courseid); array_push($params, $courseid);
...@@ -256,15 +280,54 @@ if ($action == 'saveconfigweek') { ...@@ -256,15 +280,54 @@ if ($action == 'saveconfigweek') {
if ($courseid && $userid && $sectionname && $actiontype && $objectType && $objectName && $objectDescription && $currentUrl) { if ($courseid && $userid && $sectionname && $actiontype && $objectType && $objectName && $objectDescription && $currentUrl) {
$func = "local_notemyprogress_addLogs"; $func = "local_notemyprogress_addLogs";
} }
} }elseif($action =='savegamification'){
array_push($params, $courseid);
array_push($params, $userid);
array_push($params, $rules);
array_push($params, $levels);
array_push($params, $settings);
array_push($params, $url);
array_push($params, $section);
if($courseid && $userid && $rules && $levels && $settings && $url) {
$func = "local_notemyprogress_save_gamification_config";
}
}elseif($action =='rankable'){
array_push($params, $courseid);
array_push($params, $userid);
array_push($params, $url);
if($courseid && $userid) {
$func = "local_notemyprogress_set_rankable_player";
}
}elseif($action =='saveEnable'){
array_push($params, $courseid);
array_push($params, $userid);
array_push($params,$enable);
array_push($params,$url);
if($courseid && $userid) {
$func = "local_notemyprogress_save_enable";
}
}elseif($action =='studentGamificationViewed'){
array_push($params, $courseid);
array_push($params, $userid);
array_push($params,$url);
if($courseid && $userid) {
$func = "local_notemyprogress_viewed_student_lvl";
}
}
if (isset($params) && isset($func)) { if (isset($params) && isset($func)) {
call_user_func_array($func, $params); call_user_func_array($func, $params);
<<<<<<< HEAD
} else { } else {
=======
}else{
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
$message = get_string('api_invalid_data', 'local_notemyprogress'); $message = get_string('api_invalid_data', 'local_notemyprogress');
local_notemyprogress_ajax_response(array($message), 400); local_notemyprogress_ajax_response(array($message));//,$action,$courseid, $userid ,$rules , $levels, $settings, $url,$func), 442);
} }
<<<<<<< HEAD
function local_sr_metareflexion_get_week($weekcode, $courseid, $userid, $profile) function local_sr_metareflexion_get_week($weekcode, $courseid, $userid, $profile)
{ {
...@@ -357,6 +420,9 @@ function local_sr_update_lastweek($courseid, $userid, $lastweekid, $classroom_ho ...@@ -357,6 +420,9 @@ function local_sr_update_lastweek($courseid, $userid, $lastweekid, $classroom_ho
function local_notemyprogress_logsNMP($beginDate, $lastDate, $courseid, $userid, $currentUrl) function local_notemyprogress_logsNMP($beginDate, $lastDate, $courseid, $userid, $currentUrl)
{ {
=======
function local_notemyprogress_logsNMP($beginDate, $lastDate, $courseid, $userid, $currentUrl) {
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
$logs = new \local_notemyprogress\logs($courseid, $userid); $logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("downloaded", "logfile", "LOGFILES", "nmp", $currentUrl, "File that contains all the activities performed on the moodle course in a time interval"); $logs->addLogsNMP("downloaded", "logfile", "LOGFILES", "nmp", $currentUrl, "File that contains all the activities performed on the moodle course in a time interval");
$jsonData = $logs->searchLogsNMP($beginDate, $lastDate); $jsonData = $logs->searchLogsNMP($beginDate, $lastDate);
...@@ -471,8 +537,13 @@ function local_notemyprogress_generate_dropout_data($courseid, $userid, $profile ...@@ -471,8 +537,13 @@ function local_notemyprogress_generate_dropout_data($courseid, $userid, $profile
$dropout = new \local_notemyprogress\dropout($courseid, $userid); $dropout = new \local_notemyprogress\dropout($courseid, $userid);
$dropout->generate_data(); $dropout->generate_data();
local_notemyprogress_ajax_response([], "ok", true, 200); local_notemyprogress_ajax_response([], "ok", true, 200);
<<<<<<< HEAD
} else { } else {
local_notemyprogress_ajax_response([], "", false, 400); local_notemyprogress_ajax_response([], "", false, 400);
=======
}else{
local_notemyprogress_ajax_response([], "", false, 402);
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
} }
} }
...@@ -490,7 +561,6 @@ function local_notemyprogress_get_student_sessions($weekcode, $courseid, $userid ...@@ -490,7 +561,6 @@ function local_notemyprogress_get_student_sessions($weekcode, $courseid, $userid
function local_notemyprogress_downloadMoodleLogs($beginDate, $lastDate, $courseid, $userid, $currentUrl) function local_notemyprogress_downloadMoodleLogs($beginDate, $lastDate, $courseid, $userid, $currentUrl)
{ {
$logs = new \local_notemyprogress\logs($courseid, $userid); $logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("downloaded", "logfile", "LOGFILES", "moodle", $currentUrl, "File that contains all the activities performed on the Note My Progress plugin in a time interval"); $logs->addLogsNMP("downloaded", "logfile", "LOGFILES", "moodle", $currentUrl, "File that contains all the activities performed on the Note My Progress plugin in a time interval");
$jsonData = $logs->searchLogsMoodle($beginDate, $lastDate); $jsonData = $logs->searchLogsMoodle($beginDate, $lastDate);
local_notemyprogress_ajax_response(array("jsonData" => $jsonData)); local_notemyprogress_ajax_response(array("jsonData" => $jsonData));
...@@ -500,5 +570,49 @@ function local_notemyprogress_addLogs($sectionname, $actiontype, $courseid, $use ...@@ -500,5 +570,49 @@ function local_notemyprogress_addLogs($sectionname, $actiontype, $courseid, $use
{ {
$logs = new \local_notemyprogress\logs($courseid, $userid); $logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP($actiontype, $objectType, $sectionname, $objectName, $currentUrl, $objectDescription); $logs->addLogsNMP($actiontype, $objectType, $sectionname, $objectName, $currentUrl, $objectDescription);
<<<<<<< HEAD
local_notemyprogress_ajax_response(array("ok" => "ok")); local_notemyprogress_ajax_response(array("ok" => "ok"));
} }
=======
local_notemyprogress_ajax_response(array("ok"=>"ok"));
}
function local_notemyprogress_save_gamification_config($courseid, $userid, $rules, $levels, $settings, $url,$section){
$logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("Saved", $section, "CONFIGURATION_GAMIFICATION", "configuration_gamification", $url, "GamificationSaved");
$configLevels = new \local_notemyprogress\configgamification($courseid, $userid);
$configLevels->save_levels($levels, $settings, $rules);
//$configLevels->save_enable($enable);
$message = get_string('fml_api_save_successful', 'local_notemyprogress');
local_notemyprogress_ajax_response($message);
}
function local_notemyprogress_set_rankable_player($courseid, $userid,$url){
$logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("Saved", "section", "STUDENT_GAMIFICATION", "student_gamification", $url, "GamificationSaved");
GLobal $DB;
$sql = "update {notemyprogress_xp} set rankable = ? where courseid = ? and userid = ?";
$DB->execute($sql, array(1,$courseid, $userid));
// $sql = "UPDATE {notemyprogress_xp} SET rankable = 1 WHERE courseid = 2 AND userid = 3";
// $DB->execute($sql);
$message = get_string('fml_api_save_successful', 'local_notemyprogress');
local_notemyprogress_ajax_response($message);
}
function local_notemyprogress_save_enable($courseid, $userid, $enable,$url){
$logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("Saved", "section", "CONFIGURATION_GAMIFICATION", "configuration_gamification", $url, "GamificationSaved");
$configLevels = new \local_notemyprogress\configgamification($courseid, $userid);
$configLevels->save_enable($enable);
$message = get_string('fml_api_save_successful', 'local_notemyprogress');
local_notemyprogress_ajax_response($message);
}
function local_notemyprogress_viewed_student_lvl($courseid, $userid,$url){
$logs = new \local_notemyprogress\logs($courseid, $userid);
$logs->addLogsNMP("Viewed", "section", "STUDENT_GAMIFICATION", "student_gamification", $url, "GamificationSaved");;
// $configLevels = new \local_notemyprogress\configgamification($courseid, $userid);
// $configLevels->save_enable($enable);
// $message = get_string('fml_api_save_successful', 'local_notemyprogress');
// local_notemyprogress_ajax_response($message);
}
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
<<<<<<< HEAD
define([ define([
"local_notemyprogress/vue", "local_notemyprogress/vue",
"local_notemyprogress/vuetify", "local_notemyprogress/vuetify",
...@@ -410,3 +411,7 @@ define([ ...@@ -410,3 +411,7 @@ define([
}; };
}); });
//# sourceMappingURL=assignments.min.js.map //# sourceMappingURL=assignments.min.js.map
=======
define(["local_notemyprogress/vue","local_notemyprogress/vuetify","local_notemyprogress/axios","local_notemyprogress/moment","local_notemyprogress/pagination","local_notemyprogress/chartdynamic","local_notemyprogress/pageheader","local_notemyprogress/emailform","local_notemyprogress/helpdialog"],function(s,e,t,i,n,o,a,r,c){"use strict";return{init:function(i){s.use(e),s.component("pagination",n),s.component("chart",o),s.component("pageheader",a),s.component("emailform",r),s.component("helpdialog",c);let l=new s({delimiters:["[[","]]"],el:"#submissions",vuetify:new e,data:()=>({dialog:!1,selected_users:[],modulename:"",moduleid:!1,strings:i.strings,groups:i.groups,userid:i.userid,courseid:i.courseid,timezone:i.timezone,render_has:i.profile_render,scriptname:i.scriptname,loading:!1,errors:[],pages:i.pages,submissions:i.submissions,email_strings:i.strings.email_strings,access:i.access,assigns_submissions_colors:i.assigns_submissions_colors,access_content_colors:i.access_content_colors,access_chart_categories:[],access_chart_series:[],access_chart_users:[],help_dialog:!1,help_contents:[],email_object_name:""}),beforeMount(){this.generate_access_content_data()},mounted(){document.querySelector("#sessions-loader").style.display="none",document.querySelector("#submissions").style.display="block",setTimeout(function(){l.setGraphicsEventListeners()},1e3)},methods:{get_help_content(){let s=[];return s.push({title:this.strings.section_help_title,description:this.strings.section_help_description}),s},update_interactions(s){this.loading=!0,this.errors=[];let e={action:"assignments",userid:this.userid,courseid:this.courseid,weekcode:s.weekcode,profile:this.render_has};return t({method:"get",url:M.cfg.wwwroot+"/local/notemyprogress/ajax.php",params:e}).then(s=>{200==s.status&&s.data.ok?(this.submissions=s.data.data.submissions,this.access=s.data.data.access,this.generate_access_content_data()):this.error_messages.push(this.strings.error_network)}).catch(s=>{this.errors.push(this.strings.api_error_network)}).finally(()=>{this.loading=!1,l.addLogsIntoDB("viewed","week_"+s.weekcode,"week_section","Week section that allows you to obtain information on a specific week"),l.setGraphicsEventListeners()}),this.data},build_assigns_submissions_chart(){let s=new Object;return s.chart={type:"column",backgroundColor:null,style:{fontFamily:"poppins"}},s.title={text:null},s.colors=this.assigns_submissions_colors,s.xAxis={categories:this.submissions.categories,crosshair:!0},s.yAxis={min:0,title:{text:this.strings.assignsubs_chart_yaxis},allowDecimals:!1},s.tooltip={formatter:function(){let s=this.x.split("</b>");s=(s=(s=s[0]||"").split("<b>"))[1]||"";let e=this.series.name,t=this.y,i=l.strings.students_text,n=l.strings.send_mail;return 1==t&&(i=l.strings.student_text),"<b>"+s+"</b><br/><b>"+e+": </b>"+t+" "+i+"<br/>"+n}},s.plotOptions={series:{cursor:"pointer",point:{events:{click:function(){l.email_object_name="assigns_submissions";let s=this.category.split("</b>");s=(s=(s=s[0]||"").split("<b>"))[1]||"",l.email_strings.subject=l.email_strings.subject_prefix+" - "+s;let e=this.x,t=this.series.colorIndex;l.dialog=!0,l.selected_users=l.submissions.users[e][t],l.moduleid=l.submissions.modules[e],l.modulename="assign",l.scriptname="test"}}}}},s.series=this.submissions.data,s},build_access_content_chart(){let s=new Object;return s.chart={type:"bar",backgroundColor:null,style:{fontFamily:"poppins"}},s.title={text:null},s.colors=this.access_content_colors,s.xAxis={categories:this.access_chart_categories,title:{text:null},crosshair:!0},s.yAxis={min:0,title:{text:this.strings.access_chart_yaxis_label},labels:{overflow:"justify"},allowDecimals:!1},s.tooltip={formatter:function(){let s=this.x,e=this.series.name,t=this.y,i=l.strings.students_text,n=l.strings.send_mail;return 1==t&&(i=l.strings.student_text),"<b>"+s+"</b><br/><b>"+e+": </b>"+t+" "+i+"<br/>"+n}},s.plotOptions={bar:{dataLabels:{enabled:!1}},series:{cursor:"pointer",point:{events:{click:function(){l.email_object_name="access_content";let s=this.category;l.email_strings.subject=l.email_strings.subject_prefix+" - "+s;let e=this.x,t=this.series.colorIndex,i=l.get_users(l.access_chart_users[e][t]);l.selected_users=i;let n=l.get_moduletype(this.category);l.modulename=n.type,l.moduleid=n.id,l.dialog=!0,l.scriptname="test"}}}}},s.series=this.access_chart_series,s},update_dialog(s){this.dialog=s},generate_access_content_data(){let s=[];this.access.users.forEach(e=>{s.push(Number(e.id))});let e=[];this.access.types.forEach(s=>{s.show&&e.push(s.type)});let t=[];this.access.modules.forEach(s=>{e.includes(s.type)&&t.push(s)});let i=[],n=[],o=[],a=[];t.forEach(e=>{i.push(e.name);let t=e.users,r=s.filter(s=>!t.includes(s));o.push(t.length),a.push(r.length),n.push([t,r])});let r=[{name:this.strings.access,data:o},{name:this.strings.no_access,data:a}];this.access_chart_categories=i,this.access_chart_series=r,this.access_chart_users=n},get_users(s){let e=[];return this.access.users.forEach(t=>{let i=Number(t.id);s.includes(i)&&e.push(t)}),e},get_moduletype(s){let e;return this.access.modules.forEach(t=>{t.name===s&&(e=t)}),e},open_chart_help(s){let e=[];var t="",i="",n="",o="";"assigns_submissions"==s?(e.push({title:this.strings.assigns_submissions_help_title,description:this.strings.assigns_submissions_help_description_p1}),e.push({description:this.strings.assigns_submissions_help_description_p2}),t="viewed",n="help",i="assigns_submissions",o="Help section that provides information about the invested time chart",l.addLogsIntoDB(t,i,n,o)):"access_content"==s&&(e.push({title:this.strings.access_content_help_title,description:this.strings.access_content_help_description_p1}),e.push({description:this.strings.access_content_help_description_p2}),t="viewed",n="help",i="access_content",o="Help section that provides information about the sessions per hour chart",l.addLogsIntoDB(t,i,n,o)),this.help_contents=e,this.help_contents.length&&(this.help_dialog=!0)},update_help_dialog(s){this.help_dialog=s},get_timezone(){return`${this.strings.ss_change_timezone} ${this.timezone}`},setGraphicsEventListeners(){let s=document.querySelectorAll(".highcharts-container");s.length<1?setTimeout(l.setGraphicsEventListeners,500):(s[0].id="submissions",s[1].id="accessContent",s.forEach(s=>{s.addEventListener("mouseenter",l.addLogsViewGraphic)}))},addLogsViewGraphic(s){event.stopPropagation();var e="",t="",i="",n="";switch(s.target.id){case"submissions":e="viewed",t="assigns_submissions",i="chart",n="Chart showing the work submited by the students";break;case"accessContent":e="viewed",t="access_content",i="chart",n="Chart showing the course content accessed by the students";break;default:e="viewed",t="",i="chart",n="A chart"}l.addLogsIntoDB(e,t,i,n)},addLogsIntoDB(s,e,n,o){let a={courseid:i.courseid,userid:i.userid,action:"addLogs",sectionname:"TASKS_MONITORING",actiontype:s,objectType:n,objectName:e,currentUrl:document.location.href,objectDescription:o};t({method:"get",url:M.cfg.wwwroot+"/local/notemyprogress/ajax.php",params:a}).then(s=>{200==s.status&&s.data.ok}).catch(s=>{})}}})}}});
//# sourceMappingURL=assignments.min.js.map
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
define([
"local_notemyprogress/vue",
"local_notemyprogress/vuetify",
"local_notemyprogress/axios",
"local_notemyprogress/alertify",
"local_notemyprogress/pageheader",
"local_notemyprogress/chartdynamic",
], function (Vue, Vuetify, Axios, Alertify, PageHeader, ChartDynamic) {
"use strict";
function init(content) {
console.log(content);
Vue.use(Vuetify);
Vue.component("pageheader", PageHeader);
Vue.component("chart", ChartDynamic);
const app = new Vue({
delimiters: ["[[", "]]"],
el: "#gamification",
vuetify: new Vuetify(),
data: {
strings: content.strings,
token: content.token,
render_has: content.profile_render,
ranking: content.ranking,
notifications: [],
loading: false,
tab: null,
levelsData: content.levels_data.levelsdata,
settings: content.levels_data.settings,
rulesData: content.levels_data.rules,
courseid: content.levels_data.courseid,
userid: content.levels_data.created_by,
enable: false,
events: content.events,
setPointsOption: "calculated",
pointsBase: 0,
pointsBaseOri: 0,
swDisableEnable: content.strings.swValue,
spreadData: [],
week_resources_categories: [],
week_resources_data: [],
week_resources_colors: "#FA4641",
indicators: content.indicators,
chartdata: content.chart_data,
},
beforeMount() {},
mounted() {
this.pointsBase = +this.settings.pointsbase;
this.pointsBaseOri = +this.settings.pointsbase;
},
computed: {},
methods: {
get_help_content() {
let help_contents = [];
let help = new Object();
help.title = this.strings.help_title;
help.description = this.strings.help_description;
help_contents.push(help);
return help_contents;
},
update_dialog(value) {
this.dialog = value;
},
update_help_dialog(value) {
this.help_dialog = value;
},
openHelpSectionModalEvent() {
this.saveInteraction(
this.pluginSectionName,
"viewed",
"section_help_dialog",
3
);
},
get_timezone() {
let information = `${this.strings.change_timezone} ${this.timezone}`;
return information;
},
saveInteraction(component, interaction, target, interactiontype) {
let data = {
action: "saveinteraction",
pluginsection: this.pluginSectionName,
component,
interaction,
target,
url: window.location.href,
interactiontype,
token: this.token,
};
Axios({
method: "post",
url: `${M.cfg.wwwroot}/local/notemyprogress/ajax.php`,
data: data,
})
.then((r) => {})
.catch((e) => {});
},
addLevel() {
let newLevel = this.levelsData.length + 1;
this.levelsData.push({
lvl: newLevel,
nam: `${this.strings.level} ${newLevel}`,
des: ``,
points: this.pointsBase * (newLevel - 1),
});
},
removeLevel() {
if (this.levelsData.length > 2) {
this.levelsData.pop();
}
},
calculatePoints(index) {
let points = this.isNumber(this.pointsBase) * index;
this.levelsData[index].points = points;
return points;
},
isNumber(x) {
if (x === "" || isNaN(x) || x == 0) {
return this.pointsBaseOri;
}
return parseInt(x);
},
save_changes(logParam) {
this.notifications = ["Do you want to save the changes"];
Alertify.confirm(this.strings.save_warning_content, () => {
this.saveGamificationConfig(logParam);
console.log(logParam);
}) // ON CONFIRM
.set({ title: this.strings.save_warning_title })
.set({
labels: {
cancel: this.strings.confirm_cancel,
ok: this.strings.confirm_ok,
},
});
},
saveGamificationConfig(logParam) {
this.loading = true;
let settings = {
tit: this.settings.tit,
des: this.settings.des,
pointsbase: this.pointsBase,
};
let data = {
courseid: this.courseid,
userid: this.userid,
action: "savegamification",
levels: JSON.stringify(this.levelsData),
settings: JSON.stringify(settings),
rules: JSON.stringify(this.rulesData),
token: this.token,
enable: this.enable,
section: logParam,
};
let url = { url: window.location.href };
Axios({
method: "post",
url:
M.cfg.wwwroot +
"/local/notemyprogress/ajax.php?courseid=" +
this.courseid +
"&userid=" +
this.userid +
"&action=savegamification&levels=" +
data.levels +
"&settings=" +
data.settings +
"&rules=" +
data.rules +
"&url=" +
url.url +
"&enable=" +
data.enable +
"&section=" +
data.section,
params: data,
})
.then((response) => {
// console.log(response);
// console.log(response.status);
// console.log(url.url);
if (response.status == 200 && response.data.ok) {
this.showNotifications(response.data.data, "success");
} else {
let message =
response.data.error || this.strings.api_error_network;
this.showNotifications(message, "error"); //in this line "error" define the kind of message send
}
})
.catch((e) => {
let message = e.response.data || this.strings.api_error_network;
this.showNotifications(message, "error");
})
.finally(() => {
this.loading = false;
});
},
showNotifications(message, type, alert = true, notify = true) {
if (alert) this.notifications.push({ message, type });
if (notify) Alertify.notify(message, type);
},
table_headers() {
let headers = [
{ text: this.strings.ranking_text, value: "ranking" },
{ text: this.strings.level, value: "level" },
{ text: this.strings.student, value: "student" },
{ text: this.strings.total, value: "total" },
{ text: this.strings.progress, value: "progress_percentage" },
];
return headers;
},
addRule() {
this.rulesData.push({
rule: "",
points: 0,
});
},
removeRule(index) {
if (this.rulesData.length > 2) {
this.rulesData.splice(index, 1);
}
},
disableEnable(swDisableEnable) {
//traitement
this.enable = swDisableEnable;
let data = {
courseid: this.courseid,
userid: this.userid,
action: "saveEnable",
enable: this.enable,
};
Axios({
method: "get",
url: M.cfg.wwwroot + "/local/notemyprogress/ajax.php",
params: data,
})
.then((response) => {
if (response.status == 200 && response.data.ok) {
this.showNotifications(response.data.data, "success");
} else {
let message =
response.data.error || this.strings.api_error_network;
this.showNotifications(message, "error"); //in this line "error" define the kind of message send
}
})
.catch((e) => {
let message = e.response.data || this.strings.api_error_network;
this.showNotifications(message, "error");
})
.finally(() => {
this.loading = false;
});
},
//? ////////////////////////////////////////////////////////////////////// ?//
//? //////////////////////////// ChartPart /////////////////////////////// ?//
//? ////////////////////////////////////////////////////////////////////// ?//
chart_spread() {
let chart = new Object();
chart.chart = {
type: "column",
backgroundColor: null,
};
chart.title = {
text: this.strings.chartTitle,
};
chart.colors = ["#118AB2"];
(chart.xAxis = {
type: "category",
labels: {
rotation: -45,
style: {
fontSize: "13px",
fontFamily: "Verdana, sans-serif",
},
},
}),
(chart.yAxis = {
min: 0,
title: {
text: this.strings.chartYaxis,
},
});
chart.legend = {
enabled: false,
};
(chart.series = [
{
name: null,
data: this.chartdata, //[["level : 1", 1]],
dataLabels: {
enabled: true,
rotation: -90,
color: "#FFFFFF",
align: "right",
format: "{point.y:.1f}", // one decimal
y: 10, // 10 pixels down from the top
style: {
fontSize: "13px",
fontFamily: "Verdana, sans-serif",
},
},
},
]),
console.log("series: ");
console.log(chart.series);
return chart;
},
/*
build_inverted_time_chart() {
console.log("enter build_inverted_time_chart ");
//console.log(this.students_planification);
//console.log("this.data_report_meta_hours = ");
//console.log(this.data_report_meta_hours);
let chart = new Object();
let meta = new Object();
meta = this.chartdata_hours_week_dedication();
console.log("meta = ");
console.log(meta);
let invest = [
{
name: meta.labels[0],
y: meta.datasets[0].data[0],
},
{
name: meta.labels[1],
y: meta.datasets[0].data[1],
},
{
name: meta.labels[2],
y: meta.datasets[0].data[2],
},
];
console.log("invest = ");
console.log(invest);
chart.chart = {
type: "bar",
backgroundColor: null,
style: { fontFamily: "poppins" },
};
chart.title = { text: null };
chart.colors = this.inverted_time_colors;
chart.xAxis = {
type: "category",
crosshair: true,
};
chart.yAxis = {
title: {
text: "Framboise",
},
};
chart.tooltip = {
shared: true,
useHTML: true,
formatter: function () {
let category_name = this.points[0].key;
let time = vue.convert_time(this.y);
return `<b>${category_name}: </b>${time}`;
},
};
chart.legend = {
enabled: false,
};
chart.series = [
{
colorByPoint: true,
data: invest,
},
];
//console.log("this.inverted_time.data = ");
//console.log(this.inverted_time.data);
// console.log("invest = ");
// console.log(invest);
return chart;
},
chartdata_hours_week_dedication() {
var data = new Object();
data.datasets = [];
let inverted =
this.render_has == "teacher"
? this.strings.inverted_time
: `${this.strings.myself} ${this.strings.inverted_time}`;
let planified =
this.render_has == "teacher"
? this.strings.planified_time
: `${this.strings.myself} ${this.strings.planified_time}`;
data.labels = [inverted, planified];
var dataset = new Object();
dataset.label = "Horas";
//console.log("data_report_meta_hours in chartdata_hours_week_dedication = ");
//console.log(this.data_report_meta_hours);
dataset.data = [
parseFloat(this.data_report_meta_hours.horas_trabajadas),
parseInt(this.data_report_meta_hours.horas_planificadas),
];
dataset.backgroundColor = ["#ffa700", "#a0c2fa"];
dataset.borderWidth = 0;
data.datasets.push(dataset);
//if (this.render_has == "student" && this.compare_with_course) {
data.labels.splice(1, 0, this.strings.inverted_time_course);
//data.labels.splice(3, 0, this.strings.planified_time_course);
dataset.data.splice(
1,
0,
parseFloat(this.course_report_hours.horas_trabajadas)
);
// dataset.data.splice(
// 3,
// 0,
// parseFloat(this.course_report_hours.horas_planificadas)
// );
dataset.backgroundColor.splice(1, 0, "#ffa700");
//dataset.backgroundColor.splice(3, 0, "#a0c2fa");
//}
//console.log("data_report_meta_hours = ");
//console.log(this.data_report_meta_hours);
//console.log("data = ");
//console.log(data);
return data;
},*/
},
});
}
return {
init: init,
};
});
...@@ -4,7 +4,11 @@ define([], function () { ...@@ -4,7 +4,11 @@ define([], function () {
document document
.querySelector("#downloadButton") .querySelector("#downloadButton")
.addEventListener("click", function () { .addEventListener("click", function () {
<<<<<<< HEAD
//console.log("clicked !"); //console.log("clicked !");
=======
console.log("clicked !");
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
}); });
}, },
}; };
......
define([
"local_notemyprogress/vue",
"local_notemyprogress/vuetify",
"local_notemyprogress/axios",
"local_notemyprogress/alertify",
"local_notemyprogress/pageheader",
], function (Vue, Vuetify, Axios, Alertify, PageHeader) {
"use strict";
function init(content) {
// console.log(content);
Vue.use(Vuetify);
Vue.component("pageheader", PageHeader);
const app = new Vue({
delimiters: ["[[", "]]"],
el: "#student_gamification",
vuetify: new Vuetify(),
data: {
strings: content.strings,
token: content.token,
render_has: content.profile_render,
indicators: content.indicators,
levelInfo: content.indicators.levelInfo,
activity: content.indicators.activity,
courseid: content.indicators.cid,
userid: content.indicators.uid,
ranking: content.ranking,
tab: null,
levelsData: content.levels_data.levelsdata,
settings: content.levels_data.settings,
error_messages: [],
save_successful: false,
},
beforeMount() {
let data = {
courseid: this.courseid,
userid: this.userid,
action: "studentGamificationViewed",
};
Axios({
method: "get",
url: M.cfg.wwwroot + "/local/notemyprogress/ajax.php",
params: data,
});
},
computed: {},
methods: {
get_help_content() {
let help_contents = [];
let help = new Object();
help.title = this.strings.help_title;
help.description = this.strings.help_description;
help_contents.push(help);
return help_contents;
},
update_dialog(value) {
this.dialog = value;
},
update_help_dialog(value) {
this.help_dialog = value;
},
openHelpSectionModalEvent() {
this.saveInteraction(
this.pluginSectionName,
"viewed",
"section_help_dialog",
3
);
},
get_timezone() {
let information = `${this.strings.change_timezone} ${this.timezone}`;
return information;
},
saveInteraction(component, interaction, target, interactiontype) {
let data = {
action: "saveinteraction",
pluginsection: this.pluginSectionName,
component,
interaction,
target,
url: window.location.href,
interactiontype,
token: content.token,
};
Axios({
method: "post",
url: `${M.cfg.wwwroot}/local/notemyprogress/ajax.php`,
data: data,
})
.then((r) => {})
.catch((e) => {});
},
table_headers() {
let headers = [
{ text: this.strings.ranking_text, value: "ranking" },
{ text: this.strings.level, value: "level" },
{ text: this.strings.student, value: "student" },
{ text: this.strings.total, value: "total" },
{ text: this.strings.progress, value: "progress_percentage" },
];
return headers;
},
activateRanking() {
location.reload();
//console.log(" cid : " + this.courseid + " UID : " + this.userid);
let data = {
action: "rankable",
pluginsection: this.pluginSectionName,
url: window.location.href,
token: content.token,
courseid: this.courseid,
userid: this.userid,
};
Axios({
method: "post",
url:
`${M.cfg.wwwroot}/local/notemyprogress/ajax.php?courseid=` +
this.courseid +
"&userid=" +
this.userid,
params: data,
})
.then((r) => {
// console.log(r);
})
.catch((e) => {});
},
},
});
}
return {
init: init,
};
});
define([
"local_notemyprogress/vue",
"local_notemyprogress/vuetify",
"local_notemyprogress/axios",
"local_notemyprogress/pagination",
"local_notemyprogress/chartstatic",
"local_notemyprogress/pageheader",
"local_notemyprogress/helpdialog",
], function (
Vue,
Vuetify,
Axios,
Pagination,
ChartStatic,
PageHeader,
HelpDialog
) {
"use strict";
function init(content) {
// console.log(content);
Vue.use(Vuetify);
Vue.component("pagination", Pagination);
Vue.component("chart", ChartStatic);
Vue.component("pageheader", PageHeader);
Vue.component("helpdialog", HelpDialog);
let vue = new Vue({
delimiters: ["[[", "]]"],
el: "#teacher",
vuetify: new Vuetify(),
data() {
return {
strings: content.strings,
groups: content.groups,
userid: content.userid,
courseid: content.courseid,
timezone: content.timezone,
render_has: content.profile_render,
indicators: content.indicators,
week_resources_colors: content.week_resources_colors,
search: null,
week_resources_categories: [],
week_resources_data: [],
help_dialog: false,
help_contents: [],
};
},
beforeMount() {
this.calculate_week_resources();
},
mounted() {
document.querySelector("#sessions-loader").style.display = "none";
document.querySelector("#teacher").style.display = "block";
},
methods: {
get_help_content() {
let contents = [];
contents.push({
title: this.strings.section_help_title,
description: this.strings.section_help_description,
});
return contents;
},
get_course_grade() {
let grade = Number(this.indicators.course.grademax);
return this.isInt(grade) ? grade : grade.toFixed(2);
},
calculate_week_resources() {
let categories = [],
data = [];
let week_name;
this.indicators.weeks.forEach((week) => {
week_name = `${week.name} ${week.position + 1}`;
categories.push(week_name);
data.push(week.cms);
});
let name = this.capitalizeFirstLetter(
this.strings.teacher_indicators_modules
);
this.week_resources_categories = categories;
this.week_resources_data = [{ name, data }];
},
build_week_resources_chart() {
let chart = new Object();
chart.chart = {
type: "bar",
backgroundColor: null,
style: { fontFamily: "poppins" },
};
chart.title = {
text: null,
};
chart.colors = this.week_resources_colors;
chart.xAxis = {
categories: this.week_resources_categories,
};
chart.yAxis = {
min: 0,
title: {
text: this.strings.teacher_indicators_week_resources_yaxis_title,
},
};
chart.legend = {
enabled: false,
};
chart.series = this.week_resources_data;
console.log(chart.series);
return chart;
},
build_weeks_sessions_chart() {
let chart = new Object();
chart.chart = {
type: "heatmap",
backgroundColor: null,
style: { fontFamily: "poppins" },
};
chart.title = {
text: null,
};
chart.xAxis = {
categories: this.strings.weeks,
};
chart.yAxis = {
categories: this.indicators.sessions.categories,
title: null,
reversed: true,
};
chart.colorAxis = {
min: 0,
minColor: "#E0E0E0",
maxColor: "#118AB2",
};
chart.legend = {
layout: "horizontal",
verticalAlign: "bottom",
};
chart.tooltip = {
formatter: function () {
let days =
vue.indicators.sessions.weeks[this.point.y][this.point.x] || "";
let xCategoryName = vue.get_point_category_name(this.point, "x");
let yCategoryName = vue.get_point_category_name(this.point, "y");
let label = vue.strings.teacher_indicators_sessions;
if (this.point.value == 1) {
label = vue.strings.teacher_indicators_session;
}
return (
"<b>" +
yCategoryName +
" " +
xCategoryName +
"</b>: " +
this.point.value +
" " +
label +
"<br/>" +
days
);
},
};
chart.series = [
{
borderWidth: 2,
borderColor: "#FAFAFA",
data: this.indicators.sessions.data,
},
];
return chart;
},
table_headers() {
let headers = [
{ text: "", value: "id", align: "center", sortable: false },
{ text: this.strings.thead_name, value: "firstname" },
{ text: this.strings.thead_lastname, value: "lastname" },
{ text: this.strings.thead_email, value: "email" },
{
text: this.strings.thead_progress,
value: "progress_percentage",
align: "center",
},
{
text: this.strings.thead_sessions,
value: "sessions_number",
align: "center",
},
{
text: this.strings.thead_time,
value: "inverted_time",
align: "center",
},
];
return headers;
},
get_picture_url(userid) {
let url = `${M.cfg.wwwroot}/user/pix.php?file=/${userid}/f1.jpg`;
return url;
},
get_percentage_progress(value) {
return `${value} %`;
},
get_progress_tooltip(item) {
let module_label = this.strings.teacher_indicators_modules;
let finished_label = this.strings.teacher_indicators_finished;
if (item.cms.complete == 1) {
module_label = this.strings.teacher_indicators_module;
finished_label = this.strings.teacher_indicators_finalized;
}
return `${item.cms.complete} ${module_label} ${finished_label} ${this.strings.of_conector} ${item.cms.total}`;
},
get_point_category_name(point, dimension) {
let series = point.series,
isY = dimension === "y",
axis = series[isY ? "yAxis" : "xAxis"];
return axis.categories[point[isY ? "y" : "x"]];
},
capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
isInt(n) {
return n % 1 === 0;
},
open_chart_help(chart) {
let contents = [];
if (chart == "week_resources") {
contents.push({
title: this.strings.week_resources_help_title,
description: this.strings.week_resources_help_description_p1,
});
contents.push({
description: this.strings.week_resources_help_description_p2,
});
} else if (chart == "weeks_sessions") {
contents.push({
title: this.strings.weeks_sessions_help_title,
description: this.strings.week_sessions_help_description_p1,
});
contents.push({
description: this.strings.week_sessions_help_description_p2,
});
} else if (chart == "progress_table") {
contents.push({
title: this.strings.progress_table_help_title,
description: this.strings.progress_table_help_description,
});
}
this.help_contents = contents;
if (this.help_contents.length) {
this.help_dialog = true;
}
},
update_help_dialog(value) {
this.help_dialog = value;
},
get_timezone() {
let information = `${this.strings.ss_change_timezone} ${this.timezone}`;
return information;
},
addLogsIntoDB(action, objectName, objectType, objectDescription) {
let data = {
courseid: content.courseid,
userid: content.userid,
action: "addLogs",
sectionname: "TEACHER_GENERAL_INDICATORS",
actiontype: action,
objectType: objectType,
objectName: objectName,
currentUrl: document.location.href,
objectDescription: objectDescription,
};
Axios({
method: "get",
url: M.cfg.wwwroot + "/local/notemyprogress/ajax.php",
params: data,
})
.then((response) => {
if (response.status == 200 && response.data.ok) {
}
})
.catch((e) => {});
},
},
});
}
return {
init: init,
};
});
define(["local_notemyprogress/vue","local_notemyprogress/vuetify","local_notemyprogress/axios","local_notemyprogress/pagination","local_notemyprogress/chartstatic","local_notemyprogress/pageheader","local_notemyprogress/helpdialog"],function(e,t,s,i,r,o,n){"use strict";return{init:function(a){e.use(t),e.component("pagination",i),e.component("chart",r),e.component("pageheader",o),e.component("helpdialog",n);let l=new e({delimiters:["[[","]]"],el:"#teacher",vuetify:new t,data:()=>({strings:a.strings,groups:a.groups,userid:a.userid,courseid:a.courseid,timezone:a.timezone,render_has:a.profile_render,indicators:a.indicators,week_resources_colors:a.week_resources_colors,search:null,week_resources_categories:[],week_resources_data:[],help_dialog:!1,help_contents:[]}),beforeMount(){this.calculate_week_resources()},mounted(){document.querySelector("#sessions-loader").style.display="none",document.querySelector("#teacher").style.display="block"},methods:{get_help_content(){let e=[];return e.push({title:this.strings.section_help_title,description:this.strings.section_help_description}),e},get_course_grade(){let e=Number(this.indicators.course.grademax);return this.isInt(e)?e:e.toFixed(2)},calculate_week_resources(){let e,t=[],s=[];this.indicators.weeks.forEach(i=>{e=`${i.name} ${i.position+1}`,t.push(e),s.push(i.cms)});let i=this.capitalizeFirstLetter(this.strings.teacher_indicators_modules);this.week_resources_categories=t,this.week_resources_data=[{name:i,data:s}]},build_week_resources_chart(){let e=new Object;return e.chart={type:"bar",backgroundColor:null,style:{fontFamily:"poppins"}},e.title={text:null},e.colors=this.week_resources_colors,e.xAxis={categories:this.week_resources_categories},e.yAxis={min:0,title:{text:this.strings.teacher_indicators_week_resources_yaxis_title}},e.legend={enabled:!1},e.series=this.week_resources_data,e},build_weeks_sessions_chart(){let e=new Object;return e.chart={type:"heatmap",backgroundColor:null,style:{fontFamily:"poppins"}},e.title={text:null},e.xAxis={categories:this.strings.weeks},e.yAxis={categories:this.indicators.sessions.categories,title:null,reversed:!0},e.colorAxis={min:0,minColor:"#E0E0E0",maxColor:"#118AB2"},e.legend={layout:"horizontal",verticalAlign:"bottom"},e.tooltip={formatter:function(){let e=l.indicators.sessions.weeks[this.point.y][this.point.x]||"",t=l.get_point_category_name(this.point,"x"),s=l.get_point_category_name(this.point,"y"),i=l.strings.teacher_indicators_sessions;return 1==this.point.value&&(i=l.strings.teacher_indicators_session),"<b>"+s+" "+t+"</b>: "+this.point.value+" "+i+"<br/>"+e}},e.series=[{borderWidth:2,borderColor:"#FAFAFA",data:this.indicators.sessions.data}],e},table_headers(){return[{text:"",value:"id",align:"center",sortable:!1},{text:this.strings.thead_name,value:"firstname"},{text:this.strings.thead_lastname,value:"lastname"},{text:this.strings.thead_email,value:"email"},{text:this.strings.thead_progress,value:"progress_percentage",align:"center"},{text:this.strings.thead_sessions,value:"sessions_number",align:"center"},{text:this.strings.thead_time,value:"inverted_time",align:"center"}]},get_picture_url:e=>`${M.cfg.wwwroot}/user/pix.php?file=/${e}/f1.jpg`,get_percentage_progress:e=>`${e} %`,get_progress_tooltip(e){let t=this.strings.teacher_indicators_modules,s=this.strings.teacher_indicators_finished;return 1==e.cms.complete&&(t=this.strings.teacher_indicators_module,s=this.strings.teacher_indicators_finalized),`${e.cms.complete} ${t} ${s} ${this.strings.of_conector} ${e.cms.total}`},get_point_category_name(e,t){let s="y"===t;return e.series[s?"yAxis":"xAxis"].categories[e[s?"y":"x"]]},capitalizeFirstLetter:e=>e.charAt(0).toUpperCase()+e.slice(1),isInt:e=>e%1==0,open_chart_help(e){let t=[];"week_resources"==e?(t.push({title:this.strings.week_resources_help_title,description:this.strings.week_resources_help_description_p1}),t.push({description:this.strings.week_resources_help_description_p2})):"weeks_sessions"==e?(t.push({title:this.strings.weeks_sessions_help_title,description:this.strings.week_sessions_help_description_p1}),t.push({description:this.strings.week_sessions_help_description_p2})):"progress_table"==e&&t.push({title:this.strings.progress_table_help_title,description:this.strings.progress_table_help_description}),this.help_contents=t,this.help_contents.length&&(this.help_dialog=!0)},update_help_dialog(e){this.help_dialog=e},get_timezone(){return`${this.strings.ss_change_timezone} ${this.timezone}`},addLogsIntoDB(e,t,i,r){let o={courseid:a.courseid,userid:a.userid,action:"addLogs",sectionname:"TEACHER_GENERAL_INDICATORS",actiontype:e,objectType:i,objectName:t,currentUrl:document.location.href,objectDescription:r};s({method:"get",url:M.cfg.wwwroot+"/local/notemyprogress/ajax.php",params:o}).then(e=>{200==e.status&&e.data.ok}).catch(e=>{})}}})}}});
//# sourceMappingURL=teacher.min.js.map
This diff is collapsed.
...@@ -20,7 +20,11 @@ define([ ...@@ -20,7 +20,11 @@ define([
"use strict"; "use strict";
function init(content) { function init(content) {
<<<<<<< HEAD
// //console.log(content); // //console.log(content);
=======
// console.log(content);
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
Vue.use(Vuetify); Vue.use(Vuetify);
Vue.component("pagination", Pagination); Vue.component("pagination", Pagination);
Vue.component("chart", ChartDynamic); Vue.component("chart", ChartDynamic);
...@@ -467,7 +471,11 @@ define([ ...@@ -467,7 +471,11 @@ define([
Axios({ Axios({
method: "get", method: "get",
url: M.cfg.wwwroot + "/local/notemyprogress/ajax.php", url: M.cfg.wwwroot + "/local/notemyprogress/ajax.php",
<<<<<<< HEAD
params: data, params: data,
=======
data: data,
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
}) })
.then((response) => { .then((response) => {
if (response.status == 200 && response.data.ok) { if (response.status == 200 && response.data.ok) {
......
...@@ -20,7 +20,11 @@ define([ ...@@ -20,7 +20,11 @@ define([
"use strict"; "use strict";
function init(content) { function init(content) {
<<<<<<< HEAD
// //console.log(content); // //console.log(content);
=======
// console.log(content);
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
Vue.use(Vuetify); Vue.use(Vuetify);
Vue.component("pagination", Pagination); Vue.component("pagination", Pagination);
Vue.component("chart", ChartStatic); Vue.component("chart", ChartStatic);
...@@ -183,7 +187,13 @@ define([ ...@@ -183,7 +187,13 @@ define([
backgroundColor: null, backgroundColor: null,
style: { fontFamily: "poppins" }, style: { fontFamily: "poppins" },
}; };
<<<<<<< HEAD
chart.title = { text: null }; chart.title = { text: null };
=======
chart.title = {
text: null,
};
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
chart.colors = this.inverted_time_colors; chart.colors = this.inverted_time_colors;
chart.xAxis = { chart.xAxis = {
type: "category", type: "category",
......
...@@ -218,6 +218,7 @@ define([ ...@@ -218,6 +218,7 @@ define([
params: data, params: data,
}) })
.then((response) => { .then((response) => {
<<<<<<< HEAD
//console.log("then1"); //console.log("then1");
if (response.status == 200 && response.data.ok) { if (response.status == 200 && response.data.ok) {
//console.log("then1.2"); //console.log("then1.2");
...@@ -246,6 +247,36 @@ define([ ...@@ -246,6 +247,36 @@ define([
//console.log("finally1"); //console.log("finally1");
this.saving_loader = false; this.saving_loader = false;
//console.log("finally2"); //console.log("finally2");
=======
console.log("then1");
if (response.status == 200 && response.data.ok) {
console.log("then1.2");
this.settings = response.data.data.settings;
console.log("then1.3");
Alertify.success(this.strings.save_successful);
console.log("then1.4");
this.save_successful = true;
console.log("then1.5");
} else {
console.log("then1.6");
Alertify.error(this.strings.error_network);
console.log("then1.7");
this.error_messages.push(this.strings.error_network);
console.log("then1.8");
}
})
.catch((e) => {
console.log("catch1");
Alertify.error(this.strings.error_network);
console.log("catch2");
this.error_messages.push(this.strings.error_network);
console.log("catch3");
})
.finally(() => {
console.log("finally1");
this.saving_loader = false;
console.log("finally2");
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
//this.addLogsIntoDB("saved", "configuration", "weeks", "Saved a new configuration for the weeks !"); //this.addLogsIntoDB("saved", "configuration", "weeks", "Saved a new configuration for the weeks !");
}); });
}, },
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Config Gamification
*
* @package local_notemyprogress
* @autor Edisson Sigua, Bryan Aguilar
* @copyright 2020 Edisson Sigua <edissonf.sigua@gmail.com>, Bryan Aguilar <bryan.aguilar6174@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace local_notemyprogress;
require_once("lib_trait.php");
use stdClass;
use DirectoryIterator;
use core_collator;
use core_component;
use core_plugin_manager;
class configgamification {
use \lib_trait;
public $course;
public $user;
public $levelsData;
function __construct($course, $userid){
$this->course = self::get_course($course);
$this->user = self::get_user($userid);
$this->levelsData = self::get_levels_data();
$this->levelsData = self::get_first_levels();
}
/**
*verify That There Are Levels,If There Are No Creation ByDefault
*
* @return array A list with gaming levels of the course
* @throws coding_exception | dml_exception
*/
public function get_first_levels(){
$levelsData = $this->levelsData;
if(!$levelsData){
$levelsData = self::create_first_levels();
$this->levelsData = $levelsData;
}
return $levelsData;
}
/**
* Create the first two levels (default levels) of NoteMyProgress in a course.This function is executed
* automatically for each course.
*
* @return stdClass An object with the levels created
* @throws dml_exception
*/
private function create_first_levels(){
global $DB;
$levelsInfo[] = array('lvl' => 1, 'name' => 'Level 1', 'des' => '', 'points' => 0);
$levelsInfo[] = array('lvl' => 2, 'name' => 'Level 2', 'des' => '', 'points' => 120);
$settings = array(
'pointsbase' => 120,
'tit' => 'Raise your level while learning',
'des' => 'Interact with your course make you stronger'
);
$levelsData = new stdClass();
$levelsData->levelsdata = json_encode($levelsInfo);
$levelsData->settings = json_encode($settings);
$levelsData->rules = json_encode(self::default_rules());
$levelsData->courseid = $this->course->id;
$levelsData->created_by = $this->user->id;
$levelsData->modified_by = $this->user->id;
$levelsData->timecreated = self::now_timestamp();
$levelsData->timemodified = self::now_timestamp();
$id = $DB->insert_record("notemyprogress_levels_data", $levelsData, true);
$levelsData->id = $id;
return $levelsData;
}
/**
* Gets information about the level configuration
*
* @return array a list with the weeks configured in a course
*/
public function get_levels_data(){
global $DB;
$levelsData = $DB->get_record_select(
"notemyprogress_levels_data",
'courseid = ? AND timedeleted IS NULL',
array($this->course->id));
if($levelsData){
$levelsData->levelsdata = json_decode($levelsData->levelsdata);
$levelsData->settings = json_decode($levelsData->settings);
$levelsData->rules = json_decode($levelsData->rules);
}
$sql = "SELECT enablegamification from {notemyprogress_gamification} where courseid=? AND timecreated=? ";
$value = $DB->get_record_sql($sql, array("courseid="=>($courseid),"timecreated="=>$timecrated->maximum));
return $levelsData;
}
/**
* Save the Gaming Levels of NotemyProgress configured in a course
*
* @param array $ Levels Levels to Save
*
* @return void
* @throws Exception
*/
public function save_levels($levelsInfo, $settings, $rules){
global $DB;
self::delete_levels();
$levelsData = new stdClass();
$levelsData->levelsdata = ($levelsInfo);
$levelsData->settings = ($settings);
$levelsData->rules = ($rules);
$levelsData->courseid = $this->course->id;
$levelsData->created_by = $this->user->id;
$levelsData->modified_by = $this->user->id;
$levelsData->timecreated = self::now_timestamp();
$levelsData->timemodified = self::now_timestamp();
$id = $DB->insert_record("notemyprogress_levels_data", $levelsData, true);
$levelsData->id = $id;
return $levelsData;
}
public function save_enable($enable){
global $DB;
$param = new stdClass();
$param->courseid = $this->course->id;
$param->userid = $this->user->id;
if ($enable){ $param->enablegamification =1;}else{ $param->enablegamification =0;}
$param->timecreated = self::now_timestamp();
//if ($timecreated == null){$result = 1;}
//if ($timecreated === null){$result = 2;}
//if ($timecreated == 'null'){$result = 3;}
//if ($timecreated->maximum == null){$result = 9;}
//if ($timecreated->maximum === null){$result = 10;}
$DB->insert_record("notemyprogress_gamification", $param,true);
}
/**
* Eliminates the Gaming Levels of NoteMyProgress configured in a course
*
* @return void
* @throws dml_exception
*/
public function delete_levels(){
global $DB;
$levelsData = $this->levelsData;
$id = $levelsData->id;
$sql = "update {notemyprogress_levels_data} set timedeleted = ? where id = ?";
$DB->execute($sql, array(self::now_timestamp() , $id));
}
/**
* Get the default gamification rules
*
* @return array a list of rules configured in a course
*/
public function default_rules() {
$ruleset[] = array('rule' => '\mod_book\event\course_module_viewed', 'points' => 5);
$ruleset[] = array('rule' => '\mod_page\event\course_module_viewed', 'points' => 10);
$ruleset[] = array('rule' => '\mod_forum\event\discussion_subscription_created', 'points' => 20);
$ruleset[] = array('rule' => '\core\event\course_viewed', 'points' => 2);
return $ruleset;
}
/**
* Get a list of events.
*/
public final function events_list() {
$list = [];
$coreevents = $this->get_core_events();
$coreevents = [get_string('coresystem') => array_reduce(array_keys($coreevents), function($carry, $prefix) use ($coreevents) {
return array_merge($carry, array_reduce($coreevents[$prefix], function($carry, $eventclass) use ($prefix) {
$infos = self::get_event_infos($eventclass);
if ($infos) {
$name = get_string('tg_colon', 'local_notemyprogress', [
'a' => $prefix,
'b' => $infos['name']
]);
$carry = array('name' => $name, 'event' => $infos['eventname']);
}
return $carry;
}, []));
}, [])];
foreach ($coreevents as $event) {
$list[] = $event;
}
// Get module events.
$list = array_merge($list, self::get_events_list_from_plugintype('mod'));
return $list;
}
/**
* Get the core events.
*
* @return array The keys are translated subsystem names, the values are the classes.
*/
protected function get_core_events() {
// Add some system events.
return [get_string('course') => [
'\\core\\event\\course_viewed',
]];
}
/**
* Return the info about an event.
*
* The key 'name' is added to contain the readable name of the event.
* It is done here because debugging is turned off and some events use
* deprecated strings.
*
* We also add the key 'isdeprecated' which indicates whether the event
* is obsolete or not.
*
* @param string $class The name of the event class.
* @return array|false
*/
public static function get_event_infos($class) {
global $CFG;
$infos = false;
// We need to disable debugging as some events can be deprecated.
$debuglevel = $CFG->debug;
$debugdisplay = $CFG->debugdisplay;
set_debugging(0, false);
// Check that the event exists, and is not an abstract event.
if (method_exists($class, 'get_static_info')) {
$ref = new \ReflectionClass($class);
if (!$ref->isAbstract()) {
$infos = $class::get_static_info();
$infos['name'] = method_exists($class, 'get_name_with_info') ? $class::get_name_with_info() : $class::get_name();
$infos['isdeprecated'] = method_exists($class, 'is_deprecated') ? $class::is_deprecated() : false;
}
}
// Restore debugging.
set_debugging($debuglevel, $debugdisplay);
return $infos;
}
/**
* Get events from plugin type.
*
* @param string $plugintype Plugin type.
* @return array
*/
protected static function get_events_list_from_plugintype($plugintype) {
$list = [];
// Loop over each plugin of the type.
$pluginlist = core_component::get_plugin_list($plugintype);
foreach ($pluginlist as $plugin => $directory) {
$component = $plugintype . '_' . $plugin;
$events = self::get_events_list_from_plugin($component);
// If we found events for this plugin, we add them to the list.
if (!empty($events)) {
//$pluginmanager = core_plugin_manager::instance();
//$plugininfo = $pluginmanager->get_plugin_info($component);
foreach ($events as $event) {
$list[] = $event;
}
}
}
return $list;
}
/**
* Get the events list from a plugin.
*
* From 3.1 we could be using core_component::get_component_classes_in_namespace().
*
* @param string $component The plugin's component name.
* @return array
*/
protected static function get_events_list_from_plugin($component) {
$directory = core_component::get_component_directory($component);
$plugindirectory = $directory . '/classes/event';
if (!is_dir($plugindirectory)) {
return [];
}
// Get the plugin's events.
$eventclasses = static::get_event_classes_from_component($component);
$pluginmanager = core_plugin_manager::instance();
$plugininfo = $pluginmanager->get_plugin_info($component);
// Reduce to the participating, non-deprecated event.
$events = array_reduce($eventclasses, function($carry, $class) use ($plugininfo) {
$infos = self::get_event_infos($class);
if (empty($infos)) {
// Skip rare case where infos aren't found.
return $carry;
} else if ($infos['edulevel'] != \core\event\base::LEVEL_PARTICIPATING) {
// Skip events that are not of level 'participating'.
return $carry;
}
// $carry[$infos['eventname']] = get_string('tg_colon', 'local_notemyprogress', [
// 'a' => $plugininfo->displayname,
// 'b' => $infos['name']
// ]);
$name = get_string('tg_colon', 'local_notemyprogress', [
'a' => $plugininfo->displayname,
'b' => $infos['name']
]);
$carry[] = array('name' => $name, 'event' => $infos['eventname']);
return $carry;
}, []);
// Order alphabetically.
//core_collator::asort($events, core_collator::SORT_NATURAL);
return $events;
}
/**
* Get the events classes from a component.
*
* @param string $component The component.
* @return Array of classes. Those may not be relevant (abstract, invalid, ...)
*/
public static function get_event_classes_from_component($component) {
$directory = core_component::get_component_directory($component);
$plugindirectory = $directory . '/classes/event';
if (!is_dir($plugindirectory)) {
return [];
}
$eventclasses = [];
$diriter = new DirectoryIterator($plugindirectory);
foreach ($diriter as $file) {
if ($file->isDot() || $file->isDir()) {
continue;
}
// It's a good idea to use the leading slashes because the event's property
// 'eventname' includes them as well, so for consistency sake... Also we do
// not check if the class exists because that would cause the class to be
// autoloaded which would potentially trigger debugging messages when
// it is deprecated.
$name = substr($file->getFileName(), 0, -4);
$classname = '\\' . $component . '\\event\\' . $name;
$eventclasses[] = $classname;
}
return $eventclasses;
}
/**
* Get the data needed to complete the graph.
*
* @param int $courseid the course id.
* @return array an array containing the apropriate data well formated
*/
public static function get_spread_chart($courseid){
Global $DB;
$resultat = [];
$levelsData = "SELECT MAX(level) as lvl from {notemyprogress_xp} where courseid=?";
$lvl = $DB->get_record_sql($levelsData, array("courseid="=>($courseid)));
$i = 1;
while($i<=$lvl->lvl){
$levelCount = "SELECT COUNT(*) as cpt from {notemyprogress_xp} where courseid=? and level=?";
$cpt = $DB->get_record_sql($levelCount, array("courseid="=>($courseid),"level="=>($i)));
$string = "level {$i} :";
array_push( $resultat,[$string,intval($cpt->cpt)]);
$i = $i+1;
}
return $resultat;
}
}
\ No newline at end of file
...@@ -53,10 +53,17 @@ class configweeks ...@@ -53,10 +53,17 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Gets the last instance configured for Fliplearning weeks. If no weeks have been * Gets the last instance configured for Fliplearning weeks. If no weeks have been
* configured in a course yet, the last instance is the one created by default by the plugin. * configured in a course yet, the last instance is the one created by default by the plugin.
* *
* @return mixed a fieldset object that contains the first record that matches the query. * @return mixed a fieldset object that contains the first record that matches the query.
=======
* Gets the last instance configured for the weeks of Note My Progress.If you have not yet been
* Configured weeks in a course, the last instance is the one that creates the plugin by default.
*
* @return mixed A FieldSet object that contains the first record that Match makes with the query
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
*/ */
public function last_instance() public function last_instance()
{ {
...@@ -70,10 +77,15 @@ class configweeks ...@@ -70,10 +77,15 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Crea una nueva instancia para la configuración de semanas de Fliplearning. Esta es la instancia * Crea una nueva instancia para la configuración de semanas de Fliplearning. Esta es la instancia
* que se crea por defecto. * que se crea por defecto.
=======
* Create a new instance for the setting of weeks of Note My Progress.This is the instance
* That is created by default.
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @return mixed un objeto fieldset que contiene el registro creado * @return mixed A FieldSet object that contains the created record
*/ */
public function create_instance() public function create_instance()
{ {
...@@ -88,10 +100,15 @@ class configweeks ...@@ -88,10 +100,15 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Gets the weeks configured in Fliplearning based on the ids of the class attributes * Gets the weeks configured in Fliplearning based on the ids of the class attributes
* $course e $intance. You can specify. * $course e $intance. You can specify.
=======
* Obtain the weeks configured in Note My progress based on the IDs of class attributes
* $ Course and $ INTANCE.It can be specified
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @return array una lista con las semanas configuradas en un curso * @return Array a list with the weeks configured in a course
*/ */
public function get_weeks() public function get_weeks()
{ {
...@@ -104,10 +121,17 @@ class configweeks ...@@ -104,10 +121,17 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Adds the sections field to the weeks class variable to store the sections assigned to each week. * Adds the sections field to the weeks class variable to store the sections assigned to each week.
* *
* @return array a list with the weeks of the course and the sections assigned to each one. * @return array a list with the weeks of the course and the sections assigned to each one.
* @throws coding_exception | dml_exception * @throws coding_exception | dml_exception
=======
* Add the Sections field to the class variable weeks to store the sections assigned to each week.
*
* @return Array a list with the weeks of the course and sections assigned to each
* @throws Coding_Exception |DML_EXCEPTION.
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
*/ */
public function get_weeks_with_sections() public function get_weeks_with_sections()
{ {
...@@ -145,10 +169,15 @@ class configweeks ...@@ -145,10 +169,15 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Crea la primera semana (semana por defecto) de Fliplearning en un curso. Esta funcion se ejecuta * Crea la primera semana (semana por defecto) de Fliplearning en un curso. Esta funcion se ejecuta
* de manera automática para cada curso. * de manera automática para cada curso.
=======
* Create the first week (default week) of Note My progress in a course.This function is executed
* automatically for each course.
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @return stdClass un objeto con la semana creada * @return stdClass An object with the week created
* @throws dml_exception * @throws dml_exception
*/ */
private function create_first_week() private function create_first_week()
...@@ -352,7 +381,11 @@ class configweeks ...@@ -352,7 +381,11 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Elimina las semanas de Fliplearning configuradas en un curso * Elimina las semanas de Fliplearning configuradas en un curso
=======
* Eliminates the weeks of Note My Progress configured in a course
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @return void * @return void
* @throws dml_exception * @throws dml_exception
...@@ -369,9 +402,13 @@ class configweeks ...@@ -369,9 +402,13 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Elimina las secciones asignadas a una semana de Fliplearning * Elimina las secciones asignadas a una semana de Fliplearning
=======
* Eliminates sections assigned to a week of Note My Progress
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @param string $weekcode id de la semana a eliminar * @param string $weekcode ID of the week to eliminate
* *
* @return void * @return void
* @throws dml_exception * @throws dml_exception
...@@ -384,10 +421,14 @@ class configweeks ...@@ -384,10 +421,14 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Guarda una semana de Fliplearning configurada en un curso * Guarda una semana de Fliplearning configurada en un curso
=======
* Save a week of Note My Progress configured in a course
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @param object $week semana a guardar * @param Object $Week week to save
* @param int $position posicion de la semana * @param int $Position position of the week
* *
* @return void * @return void
* @throws Exception * @throws Exception
...@@ -412,10 +453,14 @@ class configweeks ...@@ -412,10 +453,14 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Guarda las secciones asignadas a una semana de Fliplearning * Guarda las secciones asignadas a una semana de Fliplearning
=======
* Save the sections assigned to a week of Note My Progress
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @param string $weekcode id de la semana a la que pertenece las secciones * @param string $Weekcode ID of the week to which the sections belong
* @param array $sections lista de secciones a guardar * @param array $sections List of Sections to Save
* *
* @return void * @return void
* @throws dml_exception * @throws dml_exception
...@@ -429,11 +474,15 @@ class configweeks ...@@ -429,11 +474,15 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Guarda una seccion asignada a una semana de Fliplearning * Guarda una seccion asignada a una semana de Fliplearning
=======
* Save a SECTION ASSIGNED A A WEEK OF NOTE MY PROGRAMS
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @param object $section sección a guardar * @param object $section Save section
* @param int $weekcode id de la semana a la que pertenece la sección * @param int $weekcode ID of the week to which the section belongs
* @param int $position posición de la sección * @param int $position Position of the section
* *
* @return void * @return void
*/ */
...@@ -452,10 +501,10 @@ class configweeks ...@@ -452,10 +501,10 @@ class configweeks
} }
/** /**
* Obtiene el nombre de una sección dado su id * Gets the name of a given section your ID
* *
* @param int $sectionid id de sección * @param int $sectionid Section ID.
* @param int $position posición de la sección * @param int $position Position of the section
* *
* @return void * @return void
*/ */
...@@ -468,13 +517,18 @@ class configweeks ...@@ -468,13 +517,18 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Returns the current week of the configured Fliplearning weeks. In case the query * Returns the current week of the configured Fliplearning weeks. In case the query
* is made after the course has ended, the last configured week is returned. * is made after the course has ended, the last configured week is returned.
=======
* Returns the current week of the scheduled weeks of Note My progress.In case the consultation
* It is done after the course is over, the last week is returned
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
* *
* @param int $last_if_course_finished parámetro entero opcional para devolver la última semana configurada * @param int $last_if_course_finished Optional whole parameter to return the last week configured
* en caso de que el curso haya terminado * In case the course has finished
* *
* @return object objeto con la semana actual a la última semana * @return Object object with the current week at the last week
*/ */
public function get_current_week($last_if_course_finished = true) public function get_current_week($last_if_course_finished = true)
{ {
...@@ -495,12 +549,18 @@ class configweeks ...@@ -495,12 +549,18 @@ class configweeks
} }
/** /**
<<<<<<< HEAD
* Toma la fecha actual al momento de hacer la llamada a la funcion y le resta 7 días para obtener * Toma la fecha actual al momento de hacer la llamada a la funcion y le resta 7 días para obtener
* el día de la peticion de la semana pasada. Si el día obtenido esta dentro de alguna de las semanas * el día de la peticion de la semana pasada. Si el día obtenido esta dentro de alguna de las semanas
* configuradas de Fliplearning entonces se retorna esa semana, de lo contratio se retorna null * configuradas de Fliplearning entonces se retorna esa semana, de lo contratio se retorna null
* =======
* @return object objeto con la semana a la que corresponde la fecha actual menos 7 días. En caso de * Take the current date at the time of making the call to the function and it has 7 days to get
* no encontrarlo se retorna null * On the day of the past week.If the day obtained is within some of the weeks
* Configured Note My Progress then returns that week, of the contracted Null returns
>>>>>>> 42271d072b5508617432803ceb2659d2d3067682
*
* @return object Object with the week to which the current date corresponds less 7 days.In case of
* Do not find it Returns NULL
*/ */
public function get_past_week() public function get_past_week()
{ {
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event Collector Observer
*
* @package local_notemyprogress
* @autor Edisson Sigua, Bryan Aguilar
* @copyright 2020 Edisson Sigua <edissonf.sigua@gmail.com>, Bryan Aguilar <bryan.aguilar6174@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace local_notemyprogress;
defined('MOODLE_INTERNAL') || die();
require_once("lib_trait.php");
use stdClass;
use DateTime;
use dml_exception;
use lang_string;
class event_strategy {
use \lib_trait;
protected $table_xp = 'notemyprogress_xp';
protected $table_log = 'notemyprogress_xp_log';
public $course;
public $user;
public $configgamification;
public function __construct($course, $userid) {
$this->course = self::get_course($course);
$this->user = self::get_user($userid);
$this->configgamification = new \local_notemyprogress\configgamification($course, $userid);
}
/**
* Manejador de eventos.
*
* @param \core\event\base $event The event.
* @return void
*/
public function collect_event(\core\event\base $event) {
if (!self::can_capture_event($event)) {
return;
}
$points = self::get_points_for_event($event);
if ($points === null) {
return;
}
if ($points > 0) {
self::increase($this->user->id, $this->course->id, $points);
self::save_log($this->user->id, $this->course->id, $points, $event->eventname);
}
}
/**
* Compruebe si el usuario puede capturar este evento.
*
* @param \core\event\base $event El evento.
* @return bool True cuando el evento es permitido.
*/
protected function can_capture_event(\core\event\base $event) {
global $SESSION;
$now = time();
$maxcount = 64;
/*
* El número máximo de acciones que contarán como puntos durante el período de tiempo dado.
* Cualquier acción posterior será ignorada. Cuando este valor está vacío o es igual a cero, no se aplica.*/
$maxactions = 10;
/* El período de tiempo (segundos) durante el cual el usuario no debe exceder un número máximo de acciones.*/
$maxtime = 60;
/*
* Se acepta nuevamente el tiempo mínimo requerido antes de que una acción que ya sucedió anteriormente.
* Una acción se considera idéntica si se colocó en el mismo contexto y objeto.
* Cuando este valor está vacío o es igual a cero, no se aplica.*/
$actiontime = 180;
$actionkey = $event->eventname . ':' . $event->contextid . ':' . $event->objectid . ':' . $event->relateduserid;
if (!isset($SESSION->local_notemyprogress_cheatguard)) {
// Init the session variable.
$SESSION->local_notemyprogress_cheatguard = [];
} else {
// Ensure that all entries are arrays, they may not be when we just upgraded the plugin.
$SESSION->local_notemyprogress_cheatguard = array_map(function($entry) {
return is_array($entry) ? $entry : [$entry];
}, $SESSION->local_notemyprogress_cheatguard);
}
// Perform the check.
if (!static::is_action_accepted($actionkey, $now, $SESSION->local_notemyprogress_cheatguard, $maxactions, $maxtime, $actiontime)) {
return false;
}
// Move the action at the end of the array.
$times = isset($SESSION->local_notemyprogress_cheatguard[$actionkey]) ? $SESSION->local_notemyprogress_cheatguard[$actionkey] : [];
unset($SESSION->local_notemyprogress_cheatguard[$actionkey]);
$SESSION->local_notemyprogress_cheatguard[$actionkey] = $times;
// Log the time at which this event happened.
$SESSION->local_notemyprogress_cheatguard[$actionkey][] = time();
// Limit the timestamps of each action to a maximum of $maxcount within the timeframe desired or
// the last 15min. We want to keep at least 15 min so that when teachers are testing changes,
// they do not get confused because actions they had just performed no longer gets blocked.
$timethreshold = $now - max([$maxtime, $actiontime, 900]);
$SESSION->local_notemyprogress_cheatguard = array_filter(array_map(function($times) use ($maxcount, $timethreshold) {
return array_slice(array_filter($times, function($time) use ($timethreshold) {
return $time > $timethreshold;
}), -$maxcount);
}, $SESSION->local_notemyprogress_cheatguard));
// Limit the array of events to $maxcount, we do not want to flood the session for no reason.
$SESSION->local_notemyprogress_cheatguard = array_slice($SESSION->local_notemyprogress_cheatguard, -$maxcount, null, true);
return true;
}
/**
* Comprueba si la acción es aceptada.
*
* @param string $action Clave de la acción.
* @param int $now Timestamp.
* @param array $log Array where keys are actions, and values are timestamp arrays.
* @param int $maxactions El máximo número de acciones.
* @param int $maxintime Tiempo durante el cual el máximo número de acciones es permitido.
* @param int $timebetweenrepeats Tiempo entre acciones repetidas.
* @return bool
*/
public static function is_action_accepted($action, $now, array $log, $maxactions, $maxintime, $timebetweenrepeats) {
if ($maxactions > 0 && $maxintime > 0) {
$timethreshold = $now - $maxintime;
$actionsintimeframe = array_reduce($log, function($carry, $times) use ($timethreshold) {
return $carry + array_reduce($times, function($carry, $time) use ($timethreshold) {
return $carry + ($time > $timethreshold ? 1 : 0);
});
}, 0);
if ($actionsintimeframe >= $maxactions) {
return false;
}
}
if ($timebetweenrepeats > 0) {
$timethreshold = $now - $timebetweenrepeats;
$times = isset($log[$action]) ? $log[$action] : [];
if (!empty($times) && max($times) > $timethreshold) {
return false;
}
}
return true;
}
/**
* Obtiene los puntos para un evento.
*
* @param \core\event\base $event event.
* @return int Points, or null.
*/
public function get_points_for_event(\core\event\base $event) {
$ruleset = $this->configgamification->get_levels_data()->rules;
foreach ($ruleset as $rule) {
if ($rule->rule == $event->eventname) {
return $rule->points;
}
}
return null;
}
/**
* Agregar puntos de experiencia.
*
* @param int $id The receiver.
* @param int $amount The amount.
*/
public function increase($userid, $courseid, $amount) {
global $DB;
$prexp = 0;
$postxp = $amount;
if ($record = self::get_user_data($userid, $courseid)) {
$prexp = (int)$record->points;
$postxp = $prexp + $amount;
$sql = "UPDATE {{$this->table_xp}}
SET points = points + :points
WHERE courseid = :courseid
AND userid = :userid";
$params = [
'points' => $amount,
'courseid' => $courseid,
'userid' => $userid
];
$DB->execute($sql, $params);
$newxp = (int)$record->points + $amount;
$newlevel = self::get_level_from_xp($newxp)->lvl;
if ($record->level != $newlevel) {
$DB->set_field($this->table_xp, 'level', $newlevel, ['courseid' => $courseid, 'userid' => $userid]);
}
} else {
self::insert($userid, $courseid, $amount);
}
}
/**
* Log a thing.
*
* @param int $userid The target.
* @param int $courseid The target.
* @param int $points The points.
* @param reason $reason The reason.
* @param DateTime|null $time When that happened.
* @return void
*/
public function save_log($userid, $courseid, $points, $eventName) {
global $DB;
$time = new DateTime();
$record = new stdClass();
$record->courseid = $courseid;
$record->userid = $userid;
$record->event = $eventName;
$record->points = $points;
$record->timecreated = $time->getTimestamp();
try {
$DB->insert_record($this->table_log, $record);
} catch (dml_exception $e) {}
}
/**
* Agregar puntos de experiencia a un usuario en la tabla notemyprogress_xp.
*
* @param int $id The receiver.
* @param int $amount The amount.
*/
public function insert($userid, $courseid, $amount) {
global $DB;
$record = new stdClass();
$record->courseid = $courseid;
$record->userid = $userid;
$record->points = $amount;
$record->level = self::get_level_from_xp($amount)->lvl;
try {
$DB->insert_record($this->table_xp, $record); //*
} catch (dml_exception $e) {}
}
/**
* Give the level from the xp points.
*
* @param int $xp The xp points.
* @return level
*/
public function get_level_from_xp($points) {
$levels = $this->configgamification->get_levels_data()->levelsdata;
for ($i = count($levels)-1; $i >= 0; $i--) {
$level = $levels[$i];
if ($level->points <= $points) {
return $level;
}
}
return $level;
}
/**
* Obtiene el próximo nivel de un usuario
*
* @return null|level
*/
public function get_next_level($userid) {
$configgamification = $this->configgamification->get_levels_data();
$levels = $configgamification->levelsdata;
$userData = self::get_user_data($userid, $this->course->id);
$levelnum = $userData->level;
if ($levelnum > count($levels)-1) {
$nextlevel = false;
} else {
$nextlevel = $levels[$levelnum];
}
// TODO: validar que pasa cuando supera el ultimo nivel
if ($nextlevel === false) {
return null;
}
return $nextlevel;
}
/**
* Obtiene la información de puntos de experiencia de un usuario
*
* @return null|response
*/
public function get_user_info() {
$response = new stdClass();
$recentCount = 3;
if (self::get_user_data($this->user->id, $this->course->id)) {
$userData = self::get_user_data($this->user->id, $this->course->id);
$nextlevel = self::get_next_level($this->user->id);
$activity = self::get_user_recent_activity($this->user->id, $this->course->id, $recentCount);
$levelInfo = self::get_level_from_xp($userData->points);
$response->points = $userData->points;
$response->level = $userData->level;
$response->activity = $activity;
$response->levelInfo = $levelInfo;
$response->uid=$this->user->id;
$response->cid=$this->course->id;
// $response->points = 1;
// $response->level = 2;
// $response->activity = 3;
// $response->levelInfo = $userData->points;
if(is_null($nextlevel)) {
// Si no existe un siguiente nivel
$response->pointsToNext = 0;
$response->progress = 100;
}else{
$response->pointsToNext = $nextlevel->points - $userData->points;
$response->progress = ($userData->points*100)/$nextlevel->points;
}
}else{return self::get_user_data($this->user->id, $this->course->id);}
return $response;
}
/**
* Obtiene un ranking con los puntos de experiencia de los usuarios
*
* @return users
*/
public function get_ranking($int) {
global $DB;
$users = array();
if ($int==1){
$sql = "SELECT * FROM {{$this->table_xp}} WHERE courseid = {$this->course->id} and rankable = 1 ORDER BY points DESC";
}else{
$sql = "SELECT * FROM {{$this->table_xp}} WHERE courseid = {$this->course->id} ORDER BY points DESC";
}
$rank = $DB->get_recordset_sql($sql);
$index = 1;
foreach($rank as $user){
$completeUser = self::get_user_from_id($user->userid);
$nextlevel = self::get_next_level($user->userid);
$aux = new stdClass();
$aux->ranking = $index;
$aux->level = $user->level;
$aux->student = $completeUser->firstname.' '.$completeUser->lastname;
$aux->total = $user->points;
if(is_null($nextlevel)) {
// Si no existe un siguiente nivel
$aux->progress_percentage = 100;
}else{
$aux->progress_percentage = ($user->points*100)/$nextlevel->points;
}
$users[] = $aux;
$index++;
}
$rank->close();
return $users;
}
/**
* Verifica si el usuario existe en la tabla de puntos de experiencia.
*
* @param int $id The receiver.
* @return stdClass|false
*/
public function get_user_data($userid, $courseid) {
global $DB;
$params = [];
$params['userid'] = $userid;
$params['courseid'] = $courseid;
return $DB->get_record($this->table_xp, array("userid"=>$userid,"courseid"=>$courseid));
}
/**
* Obtener la actividad reciente del usuario de la tabla notemyprogress_xp_log.
*
* @param int $userid El identificador del usuario.
* @param int $courseid El identificador del curso.
* @param int $count El número de registros a recuperar.
* @return activity
*/
public function get_user_recent_activity($userid, $courseid, $count = 0) {
global $DB;
$results = $DB->get_records_select($this->table_log, 'courseid = :courseid AND userid = :userid AND points > 0', [
'courseid' => $courseid,
'userid' => $userid,
], 'timecreated DESC, id DESC', '*', 0, $count);
$activities = array();
foreach($results as $row){
$desc = '';
$class = $row->event;
if (class_exists($class) && is_subclass_of($class, 'core\event\base')) {
$desc = $class::get_name();
} else {
$desc = new lang_string('somethinghappened', 'local_notemyprogress');
}
$activity = new stdClass();
$activity->timeago = self::time_ago(new DateTime('@' . $row->timecreated));
$activity->description = $desc;
$activity->points = $row->points;
$activities[] = $activity;
}
// return array_map(function($row) {
// $desc = '';
// $class = $row->event;
// if (class_exists($class) && is_subclass_of($class, 'core\event\base')) {
// $desc = $class::get_name();
// } else {
// $desc = new lang_string('somethinghappened', 'local_notemyprogress');
// }
// $activity = new stdClass();
// $activity->timeago = self::time_ago(new DateTime('@' . $row->timecreated));
// $activity->description = $desc;
// $activity->points = $row->points;
// return $activity;
// }, $results);
return $activities;
}
/**
* Obtener un timestamp de la forma hace 5 min.
*
* @param DateTime $dt Objeto de tipo DateTime.
* @return string
*/
public function time_ago(DateTime $dt) {
$now = new \DateTime();
$diff = $now->getTimestamp() - $dt->getTimestamp();
$ago = '?';
if ($diff < 15) {
$ago = get_string('tg_timenow', 'local_notemyprogress');
} else if ($diff < 45) {
$ago = get_string('tg_timeseconds', 'local_notemyprogress', $diff);
} else if ($diff < HOURSECS * 0.7) {
$ago = get_string('tg_timeminutes', 'local_notemyprogress', round($diff / 60));
} else if ($diff < DAYSECS * 0.7) {
$ago = get_string('tg_timehours', 'local_notemyprogress', round($diff / HOURSECS));
} else if ($diff < DAYSECS * 7 * 0.7) {
$ago = get_string('tg_timedays', 'local_notemyprogress', round($diff / DAYSECS));
} else if ($diff < DAYSECS * 30 * 0.7) {
$ago = get_string('tg_timeweeks', 'local_notemyprogress', round($diff / (DAYSECS * 7)));
} else if ($diff < DAYSECS * 365) {
$ago = userdate($dt->getTimestamp(), get_string('tg_timewithinayearformat', 'local_notemyprogress'));
} else {
$ago = userdate($dt->getTimestamp(), get_string('tg_timeolderyearformat', 'local_notemyprogress'));
}
return $ago;
}
}
\ No newline at end of file
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace local_notemyprogress\external;
use coding_exception;
use dml_exception;
use function end;
use external_api;
use external_function_parameters;
use external_multiple_structure;
use external_single_structure;
use external_value;
use invalid_parameter_exception;
use moodle_exception;
use restricted_context_exception;
use stdClass;
defined('MOODLE_INTERNAL') || die();
/**
* Class levels
*
* @package mod_millionaire\external
* @copyright 2019 Benedikt Kulmann <b@kulmann.biz>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class external extends external_api {
/**
* Definition of parameters for {@see get_levels}.
*
* @return external_function_parameters
*/
public static function get_levels_parameters() {
return new external_function_parameters([
'courseid' => new external_value(PARAM_INT, 'course id'),
]);
}
/**
* Definition of return type for {@see get_levels}.
*
* @return external_multiple_structure
*/
public static function get_levels_returns() {
return new external_multiple_structure(
level_dto::get_read_structure()
);
}
/**
* Get all levels.
*
* @param int $courseid
*
* @return array
* @throws coding_exception
* @throws dml_exception
* @throws invalid_parameter_exception
* @throws moodle_exception
* @throws restricted_context_exception
*/
public static function get_levels($courseid) {
$params = ['courseid' => $courseid];
self::validate_parameters(self::get_levels_parameters(), $params);
global $DB;
$levelsData = $DB->get_record_select(
"notemyprogress_levels_data",
'courseid = ? AND timedeleted IS NULL', $params);
if($levelsData){
$levelsData->levelsdata = json_decode($levelsData->levelsdata);
$levelsData->settings = json_decode($levelsData->settings);
$levelsData->rules = json_decode($levelsData->rules);
}
return $levelsData;
}
}
\ No newline at end of file
<?php
namespace local_notemyprogress\jwt;
class BeforeValidException extends \UnexpectedValueException
{
}
<?php
namespace local_notemyprogress\jwt;
class ExpiredException extends \UnexpectedValueException
{
}
<?php
namespace local_notemyprogress\jwt;
use DomainException;
use InvalidArgumentException;
use UnexpectedValueException;
/**
* JSON Web Key implementation, based on this spec:
* https://tools.ietf.org/html/draft-ietf-jose-json-web-key-41
*
* PHP version 5
*
* @category Authentication
* @package Authentication_JWT
* @author Bui Sy Nguyen <nguyenbs@gmail.com>
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
* @link https://github.com/firebase/php-jwt
*/
class JWK
{
/**
* Parse a set of JWK keys
*
* @param array $jwks The JSON Web Key Set as an associative array
*
* @return array An associative array that represents the set of keys
*
* @throws InvalidArgumentException Provided JWK Set is empty
* @throws UnexpectedValueException Provided JWK Set was invalid
* @throws DomainException OpenSSL failure
*
* @uses parseKey
*/
public static function parseKeySet(array $jwks)
{
$keys = array();
if (!isset($jwks['keys'])) {
throw new UnexpectedValueException('"keys" member must exist in the JWK Set');
}
if (empty($jwks['keys'])) {
throw new InvalidArgumentException('JWK Set did not contain any keys');
}
foreach ($jwks['keys'] as $k => $v) {
$kid = isset($v['kid']) ? $v['kid'] : $k;
if ($key = self::parseKey($v)) {
$keys[$kid] = $key;
}
}
if (0 === \count($keys)) {
throw new UnexpectedValueException('No supported algorithms found in JWK Set');
}
return $keys;
}
/**
* Parse a JWK key
*
* @param array $jwk An individual JWK
*
* @return resource|array An associative array that represents the key
*
* @throws InvalidArgumentException Provided JWK is empty
* @throws UnexpectedValueException Provided JWK was invalid
* @throws DomainException OpenSSL failure
*
* @uses createPemFromModulusAndExponent
*/
public static function parseKey(array $jwk)
{
if (empty($jwk)) {
throw new InvalidArgumentException('JWK must not be empty');
}
if (!isset($jwk['kty'])) {
throw new UnexpectedValueException('JWK must contain a "kty" parameter');
}
switch ($jwk['kty']) {
case 'RSA':
if (!empty($jwk['d'])) {
throw new UnexpectedValueException('RSA private keys are not supported');
}
if (!isset($jwk['n']) || !isset($jwk['e'])) {
throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"');
}
$pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']);
$publicKey = \openssl_pkey_get_public($pem);
if (false === $publicKey) {
throw new DomainException(
'OpenSSL error: ' . \openssl_error_string()
);
}
return $publicKey;
default:
// Currently only RSA is supported
break;
}
}
/**
* Create a public key represented in PEM format from RSA modulus and exponent information
*
* @param string $n The RSA modulus encoded in Base64
* @param string $e The RSA exponent encoded in Base64
*
* @return string The RSA public key represented in PEM format
*
* @uses encodeLength
*/
private static function createPemFromModulusAndExponent($n, $e)
{
$modulus = JWT::urlsafeB64Decode($n);
$publicExponent = JWT::urlsafeB64Decode($e);
$components = array(
'modulus' => \pack('Ca*a*', 2, self::encodeLength(\strlen($modulus)), $modulus),
'publicExponent' => \pack('Ca*a*', 2, self::encodeLength(\strlen($publicExponent)), $publicExponent)
);
$rsaPublicKey = \pack(
'Ca*a*a*',
48,
self::encodeLength(\strlen($components['modulus']) + \strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
$rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
$rsaPublicKey = \chr(0) . $rsaPublicKey;
$rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey;
$rsaPublicKey = \pack(
'Ca*a*',
48,
self::encodeLength(\strlen($rsaOID . $rsaPublicKey)),
$rsaOID . $rsaPublicKey
);
$rsaPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
\chunk_split(\base64_encode($rsaPublicKey), 64) .
'-----END PUBLIC KEY-----';
return $rsaPublicKey;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @param int $length
* @return string
*/
private static function encodeLength($length)
{
if ($length <= 0x7F) {
return \chr($length);
}
$temp = \ltrim(\pack('N', $length), \chr(0));
return \pack('Ca*', 0x80 | \strlen($temp), $temp);
}
}
This diff is collapsed.
<?php
namespace local_notemyprogress\jwt;
class SignatureInvalidException extends \UnexpectedValueException
{
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment