Merge branch 'MDL-61667-master-modelsinstall' of git://github.com/mudrd8mz/moodle
This commit is contained in:
+164
-74
@@ -40,6 +40,11 @@ class manager {
|
||||
*/
|
||||
const DEFAULT_MLBACKEND = '\mlbackend_php\processor';
|
||||
|
||||
/**
|
||||
* Name of the file where components declare their models.
|
||||
*/
|
||||
const ANALYTICS_FILENAME = 'db/analytics.php';
|
||||
|
||||
/**
|
||||
* @var \core_analytics\predictor[]
|
||||
*/
|
||||
@@ -107,7 +112,9 @@ class manager {
|
||||
$params['trained'] = 1;
|
||||
}
|
||||
if ($predictioncontext) {
|
||||
$conditions[] = "EXISTS (SELECT 'x' FROM {analytics_predictions} ap WHERE ap.modelid = am.id AND ap.contextid = :contextid)";
|
||||
$conditions[] = "EXISTS (SELECT 'x'
|
||||
FROM {analytics_predictions} ap
|
||||
WHERE ap.modelid = am.id AND ap.contextid = :contextid)";
|
||||
$params['contextid'] = $predictioncontext->id;
|
||||
}
|
||||
$sql .= ' WHERE ' . implode(' AND ', $conditions);
|
||||
@@ -502,84 +509,16 @@ class manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the models included with moodle core to the system.
|
||||
* Used to be used to add models included with the Moodle core.
|
||||
*
|
||||
* @deprecated Deprecated since Moodle 3.7 (MDL-61667) - Use lib/db/analytics.php instead.
|
||||
* @todo Remove this method in Moodle 4.1 (MDL-65186).
|
||||
* @return void
|
||||
*/
|
||||
public static function add_builtin_models() {
|
||||
|
||||
$target = self::get_target('\core\analytics\target\course_dropout');
|
||||
|
||||
// Community of inquiry indicators.
|
||||
$coiindicators = array(
|
||||
'\mod_assign\analytics\indicator\cognitive_depth',
|
||||
'\mod_assign\analytics\indicator\social_breadth',
|
||||
'\mod_book\analytics\indicator\cognitive_depth',
|
||||
'\mod_book\analytics\indicator\social_breadth',
|
||||
'\mod_chat\analytics\indicator\cognitive_depth',
|
||||
'\mod_chat\analytics\indicator\social_breadth',
|
||||
'\mod_choice\analytics\indicator\cognitive_depth',
|
||||
'\mod_choice\analytics\indicator\social_breadth',
|
||||
'\mod_data\analytics\indicator\cognitive_depth',
|
||||
'\mod_data\analytics\indicator\social_breadth',
|
||||
'\mod_feedback\analytics\indicator\cognitive_depth',
|
||||
'\mod_feedback\analytics\indicator\social_breadth',
|
||||
'\mod_folder\analytics\indicator\cognitive_depth',
|
||||
'\mod_folder\analytics\indicator\social_breadth',
|
||||
'\mod_forum\analytics\indicator\cognitive_depth',
|
||||
'\mod_forum\analytics\indicator\social_breadth',
|
||||
'\mod_glossary\analytics\indicator\cognitive_depth',
|
||||
'\mod_glossary\analytics\indicator\social_breadth',
|
||||
'\mod_imscp\analytics\indicator\cognitive_depth',
|
||||
'\mod_imscp\analytics\indicator\social_breadth',
|
||||
'\mod_label\analytics\indicator\cognitive_depth',
|
||||
'\mod_label\analytics\indicator\social_breadth',
|
||||
'\mod_lesson\analytics\indicator\cognitive_depth',
|
||||
'\mod_lesson\analytics\indicator\social_breadth',
|
||||
'\mod_lti\analytics\indicator\cognitive_depth',
|
||||
'\mod_lti\analytics\indicator\social_breadth',
|
||||
'\mod_page\analytics\indicator\cognitive_depth',
|
||||
'\mod_page\analytics\indicator\social_breadth',
|
||||
'\mod_quiz\analytics\indicator\cognitive_depth',
|
||||
'\mod_quiz\analytics\indicator\social_breadth',
|
||||
'\mod_resource\analytics\indicator\cognitive_depth',
|
||||
'\mod_resource\analytics\indicator\social_breadth',
|
||||
'\mod_scorm\analytics\indicator\cognitive_depth',
|
||||
'\mod_scorm\analytics\indicator\social_breadth',
|
||||
'\mod_survey\analytics\indicator\cognitive_depth',
|
||||
'\mod_survey\analytics\indicator\social_breadth',
|
||||
'\mod_url\analytics\indicator\cognitive_depth',
|
||||
'\mod_url\analytics\indicator\social_breadth',
|
||||
'\mod_wiki\analytics\indicator\cognitive_depth',
|
||||
'\mod_wiki\analytics\indicator\social_breadth',
|
||||
'\mod_workshop\analytics\indicator\cognitive_depth',
|
||||
'\mod_workshop\analytics\indicator\social_breadth',
|
||||
'\core_course\analytics\indicator\completion_enabled',
|
||||
'\core_course\analytics\indicator\potential_cognitive_depth',
|
||||
'\core_course\analytics\indicator\potential_social_breadth',
|
||||
'\core\analytics\indicator\any_access_after_end',
|
||||
'\core\analytics\indicator\any_access_before_start',
|
||||
'\core\analytics\indicator\any_write_action_in_course',
|
||||
'\core\analytics\indicator\read_actions',
|
||||
);
|
||||
$indicators = array();
|
||||
foreach ($coiindicators as $coiindicator) {
|
||||
$indicator = self::get_indicator($coiindicator);
|
||||
$indicators[$indicator->get_id()] = $indicator;
|
||||
}
|
||||
if (!\core_analytics\model::exists($target, $indicators)) {
|
||||
$model = \core_analytics\model::create($target, $indicators);
|
||||
}
|
||||
|
||||
// No teaching model.
|
||||
$target = self::get_target('\core\analytics\target\no_teaching');
|
||||
$timesplittingmethod = '\core\analytics\time_splitting\single_range';
|
||||
$noteacher = self::get_indicator('\core_course\analytics\indicator\no_teacher');
|
||||
$nostudent = self::get_indicator('\core_course\analytics\indicator\no_student');
|
||||
$indicators = array($noteacher->get_id() => $noteacher, $nostudent->get_id() => $nostudent);
|
||||
if (!\core_analytics\model::exists($target, $indicators)) {
|
||||
\core_analytics\model::create($target, $indicators, $timesplittingmethod);
|
||||
}
|
||||
debugging('core_analytics\manager::add_builtin_models() has been deprecated. Core models are now automatically '.
|
||||
'updated according to their declaration in the lib/db/analytics.php file.', DEBUG_DEVELOPER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -669,4 +608,155 @@ class manager {
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all the models declared by the component are up to date.
|
||||
*
|
||||
* This is intended to be called during the installation / upgrade to automatically create missing models.
|
||||
*
|
||||
* @param string $componentname The name of the component to load models for.
|
||||
* @return array \core_analytics\model[] List of actually created models.
|
||||
*/
|
||||
public static function update_default_models_for_component(string $componentname): array {
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach (static::load_default_models_for_component($componentname) as $definition) {
|
||||
if (!\core_analytics\model::exists(static::get_target($definition['target']))) {
|
||||
$result[] = static::create_declared_model($definition);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of models declared by the given component.
|
||||
*
|
||||
* @param string $componentname The name of the component to load models for.
|
||||
* @throws \coding_exception Exception thrown in case of invalid syntax.
|
||||
* @return array The $models description array.
|
||||
*/
|
||||
public static function load_default_models_for_component(string $componentname): array {
|
||||
|
||||
$dir = \core_component::get_component_directory($componentname);
|
||||
|
||||
if (!$dir) {
|
||||
// This is either an invalid component, or a core subsystem without its own root directory.
|
||||
return [];
|
||||
}
|
||||
|
||||
$file = $dir . '/' . self::ANALYTICS_FILENAME;
|
||||
|
||||
if (!is_readable($file)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$models = null;
|
||||
include($file);
|
||||
|
||||
if (!isset($models) || !is_array($models) || empty($models)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($models as &$model) {
|
||||
if (!isset($model['enabled'])) {
|
||||
$model['enabled'] = false;
|
||||
} else {
|
||||
$model['enabled'] = clean_param($model['enabled'], PARAM_BOOL);
|
||||
}
|
||||
}
|
||||
|
||||
static::validate_models_declaration($models);
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the declaration of prediction models according the syntax expected in the component's db folder.
|
||||
*
|
||||
* The expected structure looks like this:
|
||||
*
|
||||
* [
|
||||
* [
|
||||
* 'target' => '\fully\qualified\name\of\the\target\class',
|
||||
* 'indicators' => [
|
||||
* '\fully\qualified\name\of\the\first\indicator',
|
||||
* '\fully\qualified\name\of\the\second\indicator',
|
||||
* ],
|
||||
* 'timesplitting' => '\optional\name\of\the\time_splitting\class',
|
||||
* 'enabled' => true,
|
||||
* ],
|
||||
* ];
|
||||
*
|
||||
* @param array $models List of declared models.
|
||||
* @throws \coding_exception Exception thrown in case of invalid syntax.
|
||||
*/
|
||||
public static function validate_models_declaration(array $models) {
|
||||
|
||||
foreach ($models as $model) {
|
||||
if (!isset($model['target'])) {
|
||||
throw new \coding_exception('Missing target declaration');
|
||||
}
|
||||
|
||||
if (!static::is_valid($model['target'], '\core_analytics\local\target\base')) {
|
||||
throw new \coding_exception('Invalid target classname', $model['target']);
|
||||
}
|
||||
|
||||
if (empty($model['indicators']) || !is_array($model['indicators'])) {
|
||||
throw new \coding_exception('Missing indicators declaration');
|
||||
}
|
||||
|
||||
foreach ($model['indicators'] as $indicator) {
|
||||
if (!static::is_valid($indicator, '\core_analytics\local\indicator\base')) {
|
||||
throw new \coding_exception('Invalid indicator classname', $indicator);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($model['timesplitting'])) {
|
||||
if (substr($model['timesplitting'], 0, 1) !== '\\') {
|
||||
throw new \coding_exception('Expecting fully qualified time splitting classname', $model['timesplitting']);
|
||||
}
|
||||
if (!static::is_valid($model['timesplitting'], '\core_analytics\local\time_splitting\base')) {
|
||||
throw new \coding_exception('Invalid time splitting classname', $model['timesplitting']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($model['enabled']) && !isset($model['timesplitting'])) {
|
||||
throw new \coding_exception('Cannot enable a model without time splitting method specified');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the defined model.
|
||||
*
|
||||
* @param array $definition See {@link self::validate_models_declaration()} for the syntax.
|
||||
* @return \core_analytics\model
|
||||
*/
|
||||
public static function create_declared_model(array $definition): \core_analytics\model {
|
||||
|
||||
$target = static::get_target($definition['target']);
|
||||
|
||||
$indicators = [];
|
||||
|
||||
foreach ($definition['indicators'] as $indicatorname) {
|
||||
$indicator = static::get_indicator($indicatorname);
|
||||
$indicators[$indicator->get_id()] = $indicator;
|
||||
}
|
||||
|
||||
if (isset($definition['timesplitting'])) {
|
||||
$timesplitting = $definition['timesplitting'];
|
||||
} else {
|
||||
$timesplitting = false;
|
||||
}
|
||||
|
||||
$created = \core_analytics\model::create($target, $indicators, $timesplitting);
|
||||
|
||||
if (!empty($definition['enabled'])) {
|
||||
$created->enable();
|
||||
}
|
||||
|
||||
return $created;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-12
@@ -346,8 +346,6 @@ class model {
|
||||
$timesplittingid = false, $processor = null) {
|
||||
global $USER, $DB;
|
||||
|
||||
\core_analytics\manager::check_can_manage_models();
|
||||
|
||||
$indicatorclasses = self::indicator_classes($indicators);
|
||||
|
||||
$now = time();
|
||||
@@ -360,6 +358,20 @@ class model {
|
||||
$modelobj->timemodified = $now;
|
||||
$modelobj->usermodified = $USER->id;
|
||||
|
||||
if ($target->based_on_assumptions()) {
|
||||
$modelobj->trained = 1;
|
||||
}
|
||||
|
||||
if ($timesplittingid) {
|
||||
if (!\core_analytics\manager::is_valid($timesplittingid, '\core_analytics\local\time_splitting\base')) {
|
||||
throw new \moodle_exception('errorinvalidtimesplitting', 'analytics');
|
||||
}
|
||||
if (substr($timesplittingid, 0, 1) !== '\\') {
|
||||
throw new \moodle_exception('errorinvalidtimesplitting', 'analytics');
|
||||
}
|
||||
$modelobj->timesplitting = $timesplittingid;
|
||||
}
|
||||
|
||||
if ($processor &&
|
||||
!manager::is_valid($processor, '\core_analytics\classifier') &&
|
||||
!manager::is_valid($processor, '\core_analytics\regressor')) {
|
||||
@@ -375,14 +387,6 @@ class model {
|
||||
|
||||
$model = new static($modelobj);
|
||||
|
||||
if ($timesplittingid) {
|
||||
$model->enable($timesplittingid);
|
||||
}
|
||||
|
||||
if ($model->is_static()) {
|
||||
$model->mark_as_trained();
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
@@ -401,6 +405,10 @@ class model {
|
||||
|
||||
$existingmodels = $DB->get_records('analytics_models', array('target' => $target->get_id()));
|
||||
|
||||
if (!$existingmodels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$indicators && $existingmodels) {
|
||||
return true;
|
||||
}
|
||||
@@ -1049,8 +1057,6 @@ class model {
|
||||
public function enable($timesplittingid = false) {
|
||||
global $DB, $USER;
|
||||
|
||||
\core_analytics\manager::check_can_manage_models();
|
||||
|
||||
$now = time();
|
||||
|
||||
if ($timesplittingid && $timesplittingid !== $this->model->timesplitting) {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
],
|
||||
// Cannot be enabled without timesplitting defined.
|
||||
'enabled' => true,
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
'\non\existing\class\name',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'there_should_be_a_valid_fully_qualified_classname_here',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
'\core_course\analytics\indicator\no_student',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
],
|
||||
'timesplitting' => '\non\existing\class\name',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
],
|
||||
'timesplitting' => 'local_customplugin_non_fully_qualified_class_name',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of an invalid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
'\core_course\analytics\indicator\no_student',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Example of a valid db/analytics.php file content used for unit tests.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @category test
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => '\core\analytics\target\no_teaching',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
'\core_course\analytics\indicator\no_student',
|
||||
],
|
||||
'timesplitting' => '\core\analytics\time_splitting\single_range',
|
||||
'enabled' => true,
|
||||
],
|
||||
];
|
||||
@@ -150,4 +150,225 @@ class analytics_manager_testcase extends advanced_testcase {
|
||||
get_log_manager(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the {@link \core_analytics\manager::load_default_models_for_component()} implementation.
|
||||
*/
|
||||
public function test_load_default_models_for_component() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Attempting to load builtin models should always work without throwing exception.
|
||||
\core_analytics\manager::load_default_models_for_component('core');
|
||||
|
||||
// Attempting to load from a core subsystem without its own subsystem directory.
|
||||
$this->assertSame([], \core_analytics\manager::load_default_models_for_component('core_access'));
|
||||
|
||||
// Attempting to load from a non-existing subsystem.
|
||||
$this->assertSame([], \core_analytics\manager::load_default_models_for_component('core_nonexistingsubsystem'));
|
||||
|
||||
// Attempting to load from a non-existing plugin of a known plugin type.
|
||||
$this->assertSame([], \core_analytics\manager::load_default_models_for_component('mod_foobarbazquaz12240996776'));
|
||||
|
||||
// Attempting to load from a non-existing plugin type.
|
||||
$this->assertSame([], \core_analytics\manager::load_default_models_for_component('foo_bar2776327736558'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the successful execution of the {@link \core_analytics\manager::validate_models_declaration()}.
|
||||
*/
|
||||
public function test_validate_models_declaration() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// This is expected to run without an exception.
|
||||
$models = $this->load_models_from_fixture_file('no_teaching');
|
||||
\core_analytics\manager::validate_models_declaration($models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the exceptions thrown by {@link \core_analytics\manager::validate_models_declaration()}.
|
||||
*
|
||||
* @dataProvider validate_models_declaration_exceptions_provider
|
||||
* @param array $models Models declaration.
|
||||
* @param string $exception Expected coding exception message.
|
||||
*/
|
||||
public function test_validate_models_declaration_exceptions(array $models, string $exception) {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage($exception);
|
||||
\core_analytics\manager::validate_models_declaration($models);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the {@link self::test_validate_models_declaration_exceptions()}.
|
||||
*
|
||||
* @return array of (string)testcase => [(array)models, (string)expected exception message]
|
||||
*/
|
||||
public function validate_models_declaration_exceptions_provider() {
|
||||
return [
|
||||
'missing_target' => [
|
||||
$this->load_models_from_fixture_file('missing_target'),
|
||||
'Missing target declaration',
|
||||
],
|
||||
'invalid_target' => [
|
||||
$this->load_models_from_fixture_file('invalid_target'),
|
||||
'Invalid target classname',
|
||||
],
|
||||
'missing_indicators' => [
|
||||
$this->load_models_from_fixture_file('missing_indicators'),
|
||||
'Missing indicators declaration',
|
||||
],
|
||||
'invalid_indicators' => [
|
||||
$this->load_models_from_fixture_file('invalid_indicators'),
|
||||
'Invalid indicator classname',
|
||||
],
|
||||
'invalid_time_splitting' => [
|
||||
$this->load_models_from_fixture_file('invalid_time_splitting'),
|
||||
'Invalid time splitting classname',
|
||||
],
|
||||
'invalid_time_splitting_fq' => [
|
||||
$this->load_models_from_fixture_file('invalid_time_splitting_fq'),
|
||||
'Expecting fully qualified time splitting classname',
|
||||
],
|
||||
'invalid_enabled' => [
|
||||
$this->load_models_from_fixture_file('invalid_enabled'),
|
||||
'Cannot enable a model without time splitting method specified',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads models as declared in the given fixture file.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return array
|
||||
*/
|
||||
protected function load_models_from_fixture_file(string $filename) {
|
||||
global $CFG;
|
||||
|
||||
$models = null;
|
||||
|
||||
require($CFG->dirroot.'/analytics/tests/fixtures/db_analytics_php/'.$filename.'.php');
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the implementation of the {@link \core_analytics\manager::create_declared_model()}.
|
||||
*/
|
||||
public function test_create_declared_model() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminuser();
|
||||
|
||||
$declaration = [
|
||||
'target' => 'test_target_course_level_shortname',
|
||||
'indicators' => [
|
||||
'test_indicator_max',
|
||||
'test_indicator_min',
|
||||
'test_indicator_fullname',
|
||||
],
|
||||
];
|
||||
|
||||
$declarationwithtimesplitting = array_merge($declaration, [
|
||||
'timesplitting' => '\core\analytics\time_splitting\no_splitting',
|
||||
]);
|
||||
|
||||
$declarationwithtimesplittingenabled = array_merge($declarationwithtimesplitting, [
|
||||
'enabled' => true,
|
||||
]);
|
||||
|
||||
// Check that no such model exists yet.
|
||||
$target = \core_analytics\manager::get_target('test_target_course_level_shortname');
|
||||
$this->assertEquals(0, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
$this->assertFalse(\core_analytics\model::exists($target));
|
||||
|
||||
// Check that the model is created.
|
||||
$created = \core_analytics\manager::create_declared_model($declaration);
|
||||
$this->assertTrue($created instanceof \core_analytics\model);
|
||||
$this->assertTrue(\core_analytics\model::exists($target));
|
||||
$this->assertEquals(1, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
$modelid = $created->get_id();
|
||||
|
||||
// Check that created models are disabled by default.
|
||||
$existing = new \core_analytics\model($modelid);
|
||||
$this->assertEquals(0, $existing->get_model_obj()->enabled);
|
||||
$this->assertEquals(0, $DB->get_field('analytics_models', 'enabled', ['target' => $target->get_id()], MUST_EXIST));
|
||||
|
||||
// Let the admin enable the model.
|
||||
$existing->enable('\core\analytics\time_splitting\no_splitting');
|
||||
$this->assertEquals(1, $DB->get_field('analytics_models', 'enabled', ['target' => $target->get_id()], MUST_EXIST));
|
||||
|
||||
// Check that further calls create a new model.
|
||||
$repeated = \core_analytics\manager::create_declared_model($declaration);
|
||||
$this->assertTrue($repeated instanceof \core_analytics\model);
|
||||
$this->assertEquals(2, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
|
||||
// Delete the models.
|
||||
$existing->delete();
|
||||
$repeated->delete();
|
||||
$this->assertEquals(0, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
$this->assertFalse(\core_analytics\model::exists($target));
|
||||
|
||||
// Create it again, this time with time splitting method specified.
|
||||
$created = \core_analytics\manager::create_declared_model($declarationwithtimesplitting);
|
||||
$this->assertTrue($created instanceof \core_analytics\model);
|
||||
$this->assertTrue(\core_analytics\model::exists($target));
|
||||
$this->assertEquals(1, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
$modelid = $created->get_id();
|
||||
|
||||
// Even if the time splitting method was specified, the model is still not enabled automatically.
|
||||
$existing = new \core_analytics\model($modelid);
|
||||
$this->assertEquals(0, $existing->get_model_obj()->enabled);
|
||||
$this->assertEquals(0, $DB->get_field('analytics_models', 'enabled', ['target' => $target->get_id()], MUST_EXIST));
|
||||
$existing->delete();
|
||||
|
||||
// Let's define the model so that it is enabled by default.
|
||||
$enabled = \core_analytics\manager::create_declared_model($declarationwithtimesplittingenabled);
|
||||
$this->assertTrue($enabled instanceof \core_analytics\model);
|
||||
$this->assertTrue(\core_analytics\model::exists($target));
|
||||
$this->assertEquals(1, $DB->count_records('analytics_models', ['target' => $target->get_id()]));
|
||||
$modelid = $enabled->get_id();
|
||||
$existing = new \core_analytics\model($modelid);
|
||||
$this->assertEquals(1, $existing->get_model_obj()->enabled);
|
||||
$this->assertEquals(1, $DB->get_field('analytics_models', 'enabled', ['target' => $target->get_id()], MUST_EXIST));
|
||||
|
||||
// Let the admin disable the model.
|
||||
$existing->update(0, false, false);
|
||||
$this->assertEquals(0, $DB->get_field('analytics_models', 'enabled', ['target' => $target->get_id()], MUST_EXIST));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the implementation of the {@link \core_analytics\manager::update_default_models_for_component()}.
|
||||
*/
|
||||
public function test_update_default_models_for_component() {
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminuser();
|
||||
|
||||
$noteaching = \core_analytics\manager::get_target('\core\analytics\target\no_teaching');
|
||||
$dropout = \core_analytics\manager::get_target('\core\analytics\target\course_dropout');
|
||||
|
||||
$this->assertTrue(\core_analytics\model::exists($noteaching));
|
||||
$this->assertTrue(\core_analytics\model::exists($dropout));
|
||||
|
||||
foreach (\core_analytics\manager::get_all_models() as $model) {
|
||||
$model->delete();
|
||||
}
|
||||
|
||||
$this->assertFalse(\core_analytics\model::exists($noteaching));
|
||||
$this->assertFalse(\core_analytics\model::exists($dropout));
|
||||
|
||||
$updated = \core_analytics\manager::update_default_models_for_component('moodle');
|
||||
|
||||
$this->assertEquals(2, count($updated));
|
||||
$this->assertTrue(array_pop($updated) instanceof \core_analytics\model);
|
||||
$this->assertTrue(array_pop($updated) instanceof \core_analytics\model);
|
||||
$this->assertTrue(\core_analytics\model::exists($noteaching));
|
||||
$this->assertTrue(\core_analytics\model::exists($dropout));
|
||||
|
||||
$repeated = \core_analytics\manager::update_default_models_for_component('moodle');
|
||||
|
||||
$this->assertSame([], $repeated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,16 +272,14 @@ class analytics_model_testcase extends advanced_testcase {
|
||||
public function test_exists() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
global $DB;
|
||||
|
||||
$count = $DB->count_records('analytics_models');
|
||||
|
||||
// No new models added if the builtin ones already exist.
|
||||
\core_analytics\manager::add_builtin_models();
|
||||
$this->assertCount($count, $DB->get_records('analytics_models'));
|
||||
|
||||
$target = \core_analytics\manager::get_target('\core\analytics\target\no_teaching');
|
||||
$this->assertTrue(\core_analytics\model::exists($target));
|
||||
|
||||
foreach (\core_analytics\manager::get_all_models() as $model) {
|
||||
$model->delete();
|
||||
}
|
||||
|
||||
$this->assertFalse(\core_analytics\model::exists($target));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,8 +86,10 @@ class core_analytics_privacy_model_testcase extends \core_privacy\tests\provider
|
||||
|
||||
$this->setAdminUser();
|
||||
|
||||
$this->model1->enable();
|
||||
$this->model1->train();
|
||||
$this->model1->predict();
|
||||
$this->model2->enable();
|
||||
$this->model2->train();
|
||||
$this->model2->predict();
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@ information provided here is intended especially for developers.
|
||||
* \core_analytics\regressor::evaluate_regression and \core_analytics\classifier::evaluate_classification
|
||||
have been updated to include a new $trainedmodeldir param. This new param will be used to evaluate the
|
||||
existing trained model.
|
||||
* Plugins and core subsystems can now declare default prediction models by describing them in
|
||||
their db/analytics.php file. Models should not be created manually via the db/install.php
|
||||
file any more.
|
||||
* The method \core_analytics\manager::add_builtin_models() has been deprecated. The functionality
|
||||
has been replaced with automatic update of models provided by the core moodle component. There
|
||||
is no need to call this method explicitly any more. Instead, adding new models can be achieved
|
||||
by updating the lib/db/analytics.php file and bumping the core version.
|
||||
|
||||
=== 3.5 ===
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Defines the built-in prediction models provided by the Moodle core.
|
||||
*
|
||||
* @package core
|
||||
* @category analytics
|
||||
* @copyright 2019 David Mudrák <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$models = [
|
||||
[
|
||||
'target' => '\core\analytics\target\course_dropout',
|
||||
'indicators' => [
|
||||
'\core\analytics\indicator\any_access_after_end',
|
||||
'\core\analytics\indicator\any_access_before_start',
|
||||
'\core\analytics\indicator\any_write_action_in_course',
|
||||
'\core\analytics\indicator\read_actions',
|
||||
'\core_course\analytics\indicator\completion_enabled',
|
||||
'\core_course\analytics\indicator\potential_cognitive_depth',
|
||||
'\core_course\analytics\indicator\potential_social_breadth',
|
||||
'\mod_assign\analytics\indicator\cognitive_depth',
|
||||
'\mod_assign\analytics\indicator\social_breadth',
|
||||
'\mod_book\analytics\indicator\cognitive_depth',
|
||||
'\mod_book\analytics\indicator\social_breadth',
|
||||
'\mod_chat\analytics\indicator\cognitive_depth',
|
||||
'\mod_chat\analytics\indicator\social_breadth',
|
||||
'\mod_choice\analytics\indicator\cognitive_depth',
|
||||
'\mod_choice\analytics\indicator\social_breadth',
|
||||
'\mod_data\analytics\indicator\cognitive_depth',
|
||||
'\mod_data\analytics\indicator\social_breadth',
|
||||
'\mod_feedback\analytics\indicator\cognitive_depth',
|
||||
'\mod_feedback\analytics\indicator\social_breadth',
|
||||
'\mod_folder\analytics\indicator\cognitive_depth',
|
||||
'\mod_folder\analytics\indicator\social_breadth',
|
||||
'\mod_forum\analytics\indicator\cognitive_depth',
|
||||
'\mod_forum\analytics\indicator\social_breadth',
|
||||
'\mod_glossary\analytics\indicator\cognitive_depth',
|
||||
'\mod_glossary\analytics\indicator\social_breadth',
|
||||
'\mod_imscp\analytics\indicator\cognitive_depth',
|
||||
'\mod_imscp\analytics\indicator\social_breadth',
|
||||
'\mod_label\analytics\indicator\cognitive_depth',
|
||||
'\mod_label\analytics\indicator\social_breadth',
|
||||
'\mod_lesson\analytics\indicator\cognitive_depth',
|
||||
'\mod_lesson\analytics\indicator\social_breadth',
|
||||
'\mod_lti\analytics\indicator\cognitive_depth',
|
||||
'\mod_lti\analytics\indicator\social_breadth',
|
||||
'\mod_page\analytics\indicator\cognitive_depth',
|
||||
'\mod_page\analytics\indicator\social_breadth',
|
||||
'\mod_quiz\analytics\indicator\cognitive_depth',
|
||||
'\mod_quiz\analytics\indicator\social_breadth',
|
||||
'\mod_resource\analytics\indicator\cognitive_depth',
|
||||
'\mod_resource\analytics\indicator\social_breadth',
|
||||
'\mod_scorm\analytics\indicator\cognitive_depth',
|
||||
'\mod_scorm\analytics\indicator\social_breadth',
|
||||
'\mod_survey\analytics\indicator\cognitive_depth',
|
||||
'\mod_survey\analytics\indicator\social_breadth',
|
||||
'\mod_url\analytics\indicator\cognitive_depth',
|
||||
'\mod_url\analytics\indicator\social_breadth',
|
||||
'\mod_wiki\analytics\indicator\cognitive_depth',
|
||||
'\mod_wiki\analytics\indicator\social_breadth',
|
||||
'\mod_workshop\analytics\indicator\cognitive_depth',
|
||||
'\mod_workshop\analytics\indicator\social_breadth',
|
||||
],
|
||||
],
|
||||
[
|
||||
'target' => '\core\analytics\target\no_teaching',
|
||||
'indicators' => [
|
||||
'\core_course\analytics\indicator\no_teacher',
|
||||
'\core_course\analytics\indicator\no_student',
|
||||
],
|
||||
'timesplitting' => '\core\analytics\time_splitting\single_range',
|
||||
'enabled' => true,
|
||||
],
|
||||
];
|
||||
@@ -319,7 +319,4 @@ function xmldb_main_install() {
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
make_default_scale();
|
||||
make_competence_scale();
|
||||
|
||||
// Add built-in prediction models.
|
||||
\core_analytics\manager::add_builtin_models();
|
||||
}
|
||||
|
||||
@@ -774,80 +774,6 @@ function xmldb_main_upgrade($oldversion) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
$now = time();
|
||||
$admin = get_admin();
|
||||
|
||||
$targetname = '\core\analytics\target\course_dropout';
|
||||
if (!$DB->record_exists('analytics_models', array('target' => $targetname))) {
|
||||
// We can not use API calls to create the built-in models.
|
||||
$modelobj = new stdClass();
|
||||
$modelobj->target = $targetname;
|
||||
$modelobj->indicators = json_encode(array(
|
||||
'\mod_assign\analytics\indicator\cognitive_depth',
|
||||
'\mod_assign\analytics\indicator\social_breadth',
|
||||
'\mod_book\analytics\indicator\cognitive_depth',
|
||||
'\mod_book\analytics\indicator\social_breadth',
|
||||
'\mod_chat\analytics\indicator\cognitive_depth',
|
||||
'\mod_chat\analytics\indicator\social_breadth',
|
||||
'\mod_choice\analytics\indicator\cognitive_depth',
|
||||
'\mod_choice\analytics\indicator\social_breadth',
|
||||
'\mod_data\analytics\indicator\cognitive_depth',
|
||||
'\mod_data\analytics\indicator\social_breadth',
|
||||
'\mod_feedback\analytics\indicator\cognitive_depth',
|
||||
'\mod_feedback\analytics\indicator\social_breadth',
|
||||
'\mod_folder\analytics\indicator\cognitive_depth',
|
||||
'\mod_folder\analytics\indicator\social_breadth',
|
||||
'\mod_forum\analytics\indicator\cognitive_depth',
|
||||
'\mod_forum\analytics\indicator\social_breadth',
|
||||
'\mod_glossary\analytics\indicator\cognitive_depth',
|
||||
'\mod_glossary\analytics\indicator\social_breadth',
|
||||
'\mod_imscp\analytics\indicator\cognitive_depth',
|
||||
'\mod_imscp\analytics\indicator\social_breadth',
|
||||
'\mod_label\analytics\indicator\cognitive_depth',
|
||||
'\mod_label\analytics\indicator\social_breadth',
|
||||
'\mod_lesson\analytics\indicator\cognitive_depth',
|
||||
'\mod_lesson\analytics\indicator\social_breadth',
|
||||
'\mod_lti\analytics\indicator\cognitive_depth',
|
||||
'\mod_lti\analytics\indicator\social_breadth',
|
||||
'\mod_page\analytics\indicator\cognitive_depth',
|
||||
'\mod_page\analytics\indicator\social_breadth',
|
||||
'\mod_quiz\analytics\indicator\cognitive_depth',
|
||||
'\mod_quiz\analytics\indicator\social_breadth',
|
||||
'\mod_resource\analytics\indicator\cognitive_depth',
|
||||
'\mod_resource\analytics\indicator\social_breadth',
|
||||
'\mod_scorm\analytics\indicator\cognitive_depth',
|
||||
'\mod_scorm\analytics\indicator\social_breadth',
|
||||
'\mod_survey\analytics\indicator\cognitive_depth',
|
||||
'\mod_survey\analytics\indicator\social_breadth',
|
||||
'\mod_url\analytics\indicator\cognitive_depth',
|
||||
'\mod_url\analytics\indicator\social_breadth',
|
||||
'\mod_wiki\analytics\indicator\cognitive_depth',
|
||||
'\mod_wiki\analytics\indicator\social_breadth',
|
||||
'\mod_workshop\analytics\indicator\cognitive_depth',
|
||||
'\mod_workshop\analytics\indicator\social_breadth',
|
||||
));
|
||||
$modelobj->version = $now;
|
||||
$modelobj->timecreated = $now;
|
||||
$modelobj->timemodified = $now;
|
||||
$modelobj->usermodified = $admin->id;
|
||||
$DB->insert_record('analytics_models', $modelobj);
|
||||
}
|
||||
|
||||
$targetname = '\core\analytics\target\no_teaching';
|
||||
if (!$DB->record_exists('analytics_models', array('target' => $targetname))) {
|
||||
$modelobj = new stdClass();
|
||||
$modelobj->enabled = 1;
|
||||
$modelobj->trained = 1;
|
||||
$modelobj->target = $targetname;
|
||||
$modelobj->indicators = json_encode(array('\core_course\analytics\indicator\no_teacher'));
|
||||
$modelobj->timesplitting = '\core\analytics\time_splitting\single_range';
|
||||
$modelobj->version = $now;
|
||||
$modelobj->timecreated = $now;
|
||||
$modelobj->timemodified = $now;
|
||||
$modelobj->usermodified = $admin->id;
|
||||
$DB->insert_record('analytics_models', $modelobj);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2017072000.02);
|
||||
}
|
||||
|
||||
@@ -578,6 +578,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
if ($type === 'message') {
|
||||
@@ -616,6 +617,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
if ($type === 'message') {
|
||||
@@ -649,6 +651,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
if ($type === 'message') {
|
||||
@@ -756,6 +759,7 @@ function upgrade_plugins_modules($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
upgrade_plugin_mnet_functions($component);
|
||||
@@ -790,6 +794,7 @@ function upgrade_plugins_modules($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
upgrade_plugin_mnet_functions($component);
|
||||
@@ -826,6 +831,7 @@ function upgrade_plugins_modules($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
upgrade_plugin_mnet_functions($component);
|
||||
@@ -947,6 +953,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
upgrade_plugin_mnet_functions($component);
|
||||
@@ -987,6 +994,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
core_tag_area::reset_definitions_for_component($component);
|
||||
@@ -1022,6 +1030,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) {
|
||||
log_update_descriptions($component);
|
||||
external_update_descriptions($component);
|
||||
\core\task\manager::reset_scheduled_tasks_for_component($component);
|
||||
\core_analytics\manager::update_default_models_for_component($component);
|
||||
message_update_providers($component);
|
||||
\core\message\inbound\manager::update_handlers_for_component($component);
|
||||
upgrade_plugin_mnet_functions($component);
|
||||
@@ -1738,6 +1747,7 @@ function install_core($version, $verbose) {
|
||||
log_update_descriptions('moodle');
|
||||
external_update_descriptions('moodle');
|
||||
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
|
||||
\core_analytics\manager::update_default_models_for_component('moodle');
|
||||
message_update_providers('moodle');
|
||||
\core\message\inbound\manager::update_handlers_for_component('moodle');
|
||||
core_tag_area::reset_definitions_for_component('moodle');
|
||||
@@ -1805,6 +1815,7 @@ function upgrade_core($version, $verbose) {
|
||||
log_update_descriptions('moodle');
|
||||
external_update_descriptions('moodle');
|
||||
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
|
||||
\core_analytics\manager::update_default_models_for_component('moodle');
|
||||
message_update_providers('moodle');
|
||||
\core\message\inbound\manager::update_handlers_for_component('moodle');
|
||||
core_tag_area::reset_definitions_for_component('moodle');
|
||||
|
||||
Reference in New Issue
Block a user