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:
David Monllao 2017-06-15 10:21:58 +02:00
parent 584ffa4ffc
commit 1611308b58
40 changed files with 513 additions and 289 deletions

View file

@ -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;

View file

@ -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)}}});

View file

@ -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);
}
};
});

View file

@ -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;
}

View file

@ -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);

View file

@ -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());

View file

@ -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) {

View file

@ -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) {

View file

@ -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']);

View file

@ -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'));

View file

@ -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);