mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
MDL-57791 analytics: Changes after review
- Split model::predict in parts - JS promises updated according to eslint-plugin-promise - New API methods replacing direct DB queries - Reduce insights nav link display cost - Increase time limit as well as memory for big processes - Move prediction action event to core - Dataset write locking and others - Refine last time range end time - Removed dodgy splitting method id to int - Replace admin_setting_predictor output_html overwrite for write_setting overwrite - New APIs for access control - Discard invalid samples also during prediction
This commit is contained in:
parent
584ffa4ffc
commit
1611308b58
40 changed files with 513 additions and 289 deletions
|
@ -45,7 +45,7 @@ if ($hassiteconfig) {
|
|||
$logmanager = get_log_manager();
|
||||
$readers = $logmanager->get_readers('core\log\sql_reader');
|
||||
$options = array();
|
||||
$defaultreader = false;
|
||||
$defaultreader = null;
|
||||
foreach ($readers as $plugin => $reader) {
|
||||
if (!$reader->is_logging()) {
|
||||
continue;
|
||||
|
|
2
admin/tool/models/amd/build/log_info.min.js
vendored
2
admin/tool/models/amd/build/log_info.min.js
vendored
|
@ -1 +1 @@
|
|||
define(["jquery","core/str","core/modal_factory"],function(a,b,c){return{loadInfo:function(d,e){var f=a('[data-model-log-id="'+d+'"]');b.get_string("loginfo","tool_models").done(function(b){var d=a("<ul>");for(var g in e)d.append("<li>"+e[g]+"</li>");d.append("</ul>"),c.create({title:b,body:d.html(),large:!0},f)})}}});
|
||||
define(["jquery","core/str","core/modal_factory","core/notification"],function(a,b,c,d){return{loadInfo:function(e,f){var g=a('[data-model-log-id="'+e+'"]');b.get_string("loginfo","tool_models").then(function(b){var d=a("<ul>");for(var e in f)d.append("<li>"+f[e]+"</li>");return d.append("</ul>"),c.create({title:b,body:d.html(),large:!0},g)})["catch"](d.exception)}}});
|
|
@ -7,7 +7,7 @@
|
|||
/**
|
||||
* @module tool_models/log_info
|
||||
*/
|
||||
define(['jquery', 'core/str', 'core/modal_factory'], function($, str, ModalFactory) {
|
||||
define(['jquery', 'core/str', 'core/modal_factory', 'core/notification'], function($, str, ModalFactory, Notification) {
|
||||
|
||||
return {
|
||||
|
||||
|
@ -20,19 +20,21 @@ define(['jquery', 'core/str', 'core/modal_factory'], function($, str, ModalFacto
|
|||
loadInfo : function(id, info) {
|
||||
|
||||
var link = $('[data-model-log-id="' + id + '"]');
|
||||
str.get_string('loginfo', 'tool_models').done(function(langString) {
|
||||
str.get_string('loginfo', 'tool_models').then(function(langString) {
|
||||
|
||||
var bodyInfo = $("<ul>");
|
||||
for (var i in info) {
|
||||
bodyInfo.append("<li>" + info[i] + "</li>");
|
||||
}
|
||||
bodyInfo.append("</ul>");
|
||||
ModalFactory.create({
|
||||
|
||||
return ModalFactory.create({
|
||||
title: langString,
|
||||
body: bodyInfo.html(),
|
||||
large: true,
|
||||
}, link);
|
||||
});
|
||||
|
||||
}).catch(Notification.exception);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -46,10 +46,10 @@ class course_dropout extends \core_analytics\local\target\binary {
|
|||
return get_string('target:coursedropout', 'tool_models');
|
||||
}
|
||||
|
||||
public function prediction_actions(\core_analytics\prediction $prediction) {
|
||||
public function prediction_actions(\core_analytics\prediction $prediction, $includedetailsaction = false) {
|
||||
global $USER;
|
||||
|
||||
$actions = parent::prediction_actions($prediction);
|
||||
$actions = parent::prediction_actions($prediction, $includedetailsaction);
|
||||
|
||||
$sampledata = $prediction->get_sample_data();
|
||||
$studentid = $sampledata['user']->id;
|
||||
|
@ -140,13 +140,14 @@ class course_dropout extends \core_analytics\local\target\binary {
|
|||
}
|
||||
|
||||
/**
|
||||
* is_valid_sample
|
||||
* All student enrolments are valid.
|
||||
*
|
||||
* @param int $sampleid
|
||||
* @param \core_analytics\analysable $course
|
||||
* @param bool $fortraining
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid_sample($sampleid, \core_analytics\analysable $course) {
|
||||
public function is_valid_sample($sampleid, \core_analytics\analysable $course, $fortraining = true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,10 +48,10 @@ class no_teaching extends \core_analytics\local\target\binary {
|
|||
return get_string('target:noteachingactivity', 'tool_models');
|
||||
}
|
||||
|
||||
public function prediction_actions(\core_analytics\prediction $prediction) {
|
||||
public function prediction_actions(\core_analytics\prediction $prediction, $includedetailsaction = false) {
|
||||
global $USER;
|
||||
|
||||
// No need to call the parent as the only default action is view details and this target only have 1 feature.
|
||||
// No need to call the parent as the parent's action is view details and this target only have 1 feature.
|
||||
$actions = array();
|
||||
|
||||
$sampledata = $prediction->get_sample_data();
|
||||
|
@ -110,9 +110,10 @@ class no_teaching extends \core_analytics\local\target\binary {
|
|||
*
|
||||
* @param mixed $sampleid
|
||||
* @param \core_analytics\analysable $analysable
|
||||
* @param bool $fortraining
|
||||
* @return void
|
||||
*/
|
||||
public function is_valid_sample($sampleid, \core_analytics\analysable $analysable) {
|
||||
public function is_valid_sample($sampleid, \core_analytics\analysable $analysable, $fortraining = true) {
|
||||
|
||||
$course = $this->retrieve('course', $sampleid);
|
||||
|
||||
|
|
|
@ -180,8 +180,6 @@ class model_logs extends \table_sql {
|
|||
* @param bool $useinitialsbar do you want to use the initials bar.
|
||||
*/
|
||||
public function query_db($pagesize, $useinitialsbar = true) {
|
||||
global $DB;
|
||||
|
||||
$total = count($this->model->get_logs());
|
||||
$this->pagesize($pagesize, $total);
|
||||
$this->rawdata = $this->model->get_logs($this->get_page_start(), $this->get_page_size());
|
||||
|
|
|
@ -39,7 +39,7 @@ class predict_models extends \core\task\scheduled_task {
|
|||
}
|
||||
|
||||
public function execute() {
|
||||
global $DB, $OUTPUT, $PAGE;
|
||||
global $OUTPUT, $PAGE;
|
||||
|
||||
$models = \core_analytics\manager::get_all_models(true, true);
|
||||
if (!$models) {
|
||||
|
|
|
@ -39,7 +39,7 @@ class train_models extends \core\task\scheduled_task {
|
|||
}
|
||||
|
||||
public function execute() {
|
||||
global $DB, $OUTPUT, $PAGE;
|
||||
global $OUTPUT, $PAGE;
|
||||
|
||||
$models = \core_analytics\manager::get_all_models(true);
|
||||
if (!$models) {
|
||||
|
|
|
@ -63,8 +63,7 @@ if ($options['modelid'] === false || $options['timesplitting'] === false) {
|
|||
// We need admin permissions.
|
||||
\core\session\manager::set_user(get_admin());
|
||||
|
||||
$modelobj = $DB->get_record('analytics_models', array('id' => $options['modelid']), '*', MUST_EXIST);
|
||||
$model = new \core_analytics\model($modelobj);
|
||||
$model = new \core_analytics\model($options['modelid']);
|
||||
|
||||
// Evaluate its suitability to predict accurately.
|
||||
$model->enable($options['timesplitting']);
|
||||
|
|
|
@ -75,8 +75,7 @@ if ($options['filter'] !== false) {
|
|||
// We need admin permissions.
|
||||
\core\session\manager::set_user(get_admin());
|
||||
|
||||
$modelobj = $DB->get_record('analytics_models', array('id' => $options['modelid']), '*', MUST_EXIST);
|
||||
$model = new \core_analytics\model($modelobj);
|
||||
$model = new \core_analytics\model($options['modelid']);
|
||||
|
||||
mtrace(get_string('analysingsitedata', 'tool_models'));
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@ $action = required_param('action', PARAM_ALPHANUMEXT);
|
|||
$context = context_system::instance();
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/analytics:managemodels', $context);
|
||||
|
||||
$model = new \core_analytics\model($id);
|
||||
\core_analytics\manager::check_can_manage_models();
|
||||
|
||||
$params = array('id' => $id, 'action' => $action);
|
||||
$url = new \moodle_url('/admin/tool/models/model.php', $params);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue