Commit 413f19bc authored by David Monllaó's avatar David Monllaó
Browse files

MDL-59211 analytics: Make cibot happy

Part of MDL-57791 epic.
parent 1611308b
......@@ -81,4 +81,4 @@ theme/boost/scss/fontawesome/
theme/bootstrapbase/less/bootstrap/
theme/bootstrapbase/javascript/html5shiv.js
theme/bootstrapbase/amd/src/bootstrap.js
theme/bootstrapbase/less/fontawesome/
theme/bootstrapbase/less/fontawesome/
\ No newline at end of file
......@@ -82,4 +82,4 @@ theme/boost/scss/fontawesome/
theme/bootstrapbase/less/bootstrap/
theme/bootstrapbase/javascript/html5shiv.js
theme/bootstrapbase/amd/src/bootstrap.js
theme/bootstrapbase/less/fontawesome/
theme/bootstrapbase/less/fontawesome/
\ No newline at end of file
......@@ -13,11 +13,12 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/notification'], functi
/**
* Prepares a modal info for a log's results.
*
* @access public
* @param {int} id
* @return {String} HTML info
* @param {string[]} info
*/
loadInfo : function(id, info) {
loadInfo: function(id, info) {
var link = $('[data-model-log-id="' + id + '"]');
str.get_string('loginfo', 'tool_models').then(function(langString) {
......
......@@ -40,12 +40,22 @@ require_once($CFG->dirroot . '/completion/completion_completion.php');
*/
class course_dropout extends \core_analytics\local\target\binary {
protected $coursegradeitem = null;
/**
* get_name
*
* @return string
*/
public static function get_name() {
return get_string('target:coursedropout', 'tool_models');
}
/**
* prediction_actions
*
* @param \core_analytics\prediction $prediction
* @param bool $includedetailsaction
* @return \core_analytics\prediction_action[]
*/
public function prediction_actions(\core_analytics\prediction $prediction, $includedetailsaction = false) {
global $USER;
......@@ -57,17 +67,24 @@ class course_dropout extends \core_analytics\local\target\binary {
// Send a message.
$url = new \moodle_url('/message/index.php', array('user' => $USER->id, 'id' => $studentid));
$pix = new \pix_icon('t/message', get_string('sendmessage', 'message'));
$actions['studentmessage'] = new \core_analytics\prediction_action('studentmessage', $prediction, $url, $pix, get_string('sendmessage', 'message'));
$actions['studentmessage'] = new \core_analytics\prediction_action('studentmessage', $prediction, $url, $pix,
get_string('sendmessage', 'message'));
// View outline report.
$url = new \moodle_url('/report/outline/user.php', array('id' => $studentid, 'course' => $sampledata['course']->id,
'mode' => 'outline'));
$pix = new \pix_icon('i/report', get_string('outlinereport'));
$actions['viewoutlinereport'] = new \core_analytics\prediction_action('viewoutlinereport', $prediction, $url, $pix, get_string('outlinereport'));
$actions['viewoutlinereport'] = new \core_analytics\prediction_action('viewoutlinereport', $prediction, $url, $pix,
get_string('outlinereport'));
return $actions;
}
/**
* classes_description
*
* @return string[]
*/
protected static function classes_description() {
return array(
get_string('labelstudentdropoutno', 'tool_models'),
......@@ -86,10 +103,22 @@ class course_dropout extends \core_analytics\local\target\binary {
return array();
}
/**
* get_analyser_class
*
* @return string
*/
public function get_analyser_class() {
return '\\core_analytics\\local\\analyser\\student_enrolments';
}
/**
* is_valid_analysable
*
* @param \core_analytics\analysable $course
* @param bool $fortraining
* @return true|string
*/
public function is_valid_analysable(\core_analytics\analysable $course, $fortraining = true) {
global $DB;
......@@ -145,7 +174,7 @@ class course_dropout extends \core_analytics\local\target\binary {
* @param int $sampleid
* @param \core_analytics\analysable $course
* @param bool $fortraining
* @return bool
* @return true|string
*/
public function is_valid_sample($sampleid, \core_analytics\analysable $course, $fortraining = true) {
return true;
......@@ -160,7 +189,9 @@ class course_dropout extends \core_analytics\local\target\binary {
*
* @param int $sampleid
* @param \core_analytics\analysable $course
* @return void
* @param int $starttime
* @param int $endtime
* @return float
*/
protected function calculate_sample($sampleid, \core_analytics\analysable $course, $starttime = false, $endtime = false) {
......
......@@ -44,10 +44,22 @@ class no_teaching extends \core_analytics\local\target\binary {
return true;
}
/**
* get_name
*
* @return string
*/
public static function get_name() {
return get_string('target:noteachingactivity', 'tool_models');
}
/**
* prediction_actions
*
* @param \core_analytics\prediction $prediction
* @param mixed $includedetailsaction
* @return \core_analytics\prediction_action[]
*/
public function prediction_actions(\core_analytics\prediction $prediction, $includedetailsaction = false) {
global $USER;
......@@ -79,6 +91,11 @@ class no_teaching extends \core_analytics\local\target\binary {
return $actions;
}
/**
* classes_description
*
* @return string[]
*/
protected static function classes_description() {
return array(
get_string('labelteachingyes', 'tool_models'),
......@@ -96,10 +113,22 @@ class no_teaching extends \core_analytics\local\target\binary {
return array(0);
}
/**
* get_analyser_class
*
* @return string
*/
public function get_analyser_class() {
return '\\core_analytics\\local\\analyser\\site_courses';
}
/**
* is_valid_analysable
*
* @param \core_analytics\analysable $analysable
* @param mixed $fortraining
* @return true|string
*/
public function is_valid_analysable(\core_analytics\analysable $analysable, $fortraining = true) {
// The analysable is the site, so yes, it is always valid.
return true;
......@@ -108,10 +137,10 @@ class no_teaching extends \core_analytics\local\target\binary {
/**
* Only process samples which start date is getting close.
*
* @param mixed $sampleid
* @param int $sampleid
* @param \core_analytics\analysable $analysable
* @param bool $fortraining
* @return void
* @return true|string
*/
public function is_valid_sample($sampleid, \core_analytics\analysable $analysable, $fortraining = true) {
......@@ -132,7 +161,9 @@ class no_teaching extends \core_analytics\local\target\binary {
*
* @param int $sampleid
* @param \core_analytics\analysable $analysable
* @return void
* @param int $starttime
* @param int $endtime
* @return float
*/
protected function calculate_sample($sampleid, \core_analytics\analysable $analysable, $starttime = false, $endtime = false) {
......
......@@ -24,6 +24,8 @@
namespace tool_models\output\form;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot.'/lib/formslib.php');
/**
......
......@@ -24,8 +24,10 @@
namespace tool_models\output;
defined('MOODLE_INTERNAL') || die();
/**
* Typical crappy helper class with tiny functions.
* Helper class with general purpose tiny functions.
*
* @package tool_models
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
......@@ -33,6 +35,12 @@ namespace tool_models\output;
*/
class helper {
/**
* Converts a class full name to a select option key
*
* @param string $class
* @return string
*/
public static function class_to_option($class) {
// Form field is PARAM_ALPHANUMEXT and we are sending fully qualified class names
// as option names, but replacing the backslash for a string that is really unlikely
......@@ -40,6 +48,12 @@ class helper {
return str_replace('\\', '2015102400ouuu', $class);
}
/**
* option_to_class
*
* @param string $option
* @return string
*/
public static function option_to_class($option) {
// Really unlikely but yeah, I'm a bad booyyy.
return str_replace('2015102400ouuu', '\\', $option);
......
......@@ -35,8 +35,19 @@ defined('MOODLE_INTERNAL') || die();
*/
class models_list implements \renderable, \templatable {
/**
* models
*
* @var \core_analytics\model[]
*/
protected $models = array();
/**
* __construct
*
* @param \core_analytics\model[] $models
* @return void
*/
public function __construct($models) {
$this->models = $models;
}
......
......@@ -106,7 +106,8 @@ class renderer extends plugin_renderer_base {
if (isset($result->score)) {
// Score.
$output .= $OUTPUT->heading(get_string('accuracy', 'tool_models') . ': ' . round(floatval($result->score), 4) * 100 . '%', 4);
$output .= $OUTPUT->heading(get_string('accuracy', 'tool_models') . ': ' .
round(floatval($result->score), 4) * 100 . '%', 4);
}
if (!empty($result->info)) {
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
......@@ -25,6 +24,8 @@
namespace tool_models\task;
defined('MOODLE_INTERNAL') || die();
/**
* Predict system models with new data available.
*
......@@ -34,10 +35,20 @@ namespace tool_models\task;
*/
class predict_models extends \core\task\scheduled_task {
/**
* get_name
*
* @return string
*/
public function get_name() {
return get_string('predictmodels', 'tool_models');
}
/**
* Executes the prediction task.
*
* @return void
*/
public function execute() {
global $OUTPUT, $PAGE;
......
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
......@@ -25,6 +24,8 @@
namespace tool_models\task;
defined('MOODLE_INTERNAL') || die();
/**
* Train system models with new data available.
*
......@@ -34,10 +35,20 @@ namespace tool_models\task;
*/
class train_models extends \core\task\scheduled_task {
/**
* get_name
*
* @return string
*/
public function get_name() {
return get_string('trainmodels', 'tool_models');
}
/**
* Executes the prediction task.
*
* @return void
*/
public function execute() {
global $OUTPUT, $PAGE;
......
......@@ -101,6 +101,13 @@ foreach ($courses as $course) {
$courses->close();
/**
* tool_models_calculate_course_dates
*
* @param stdClass $course
* @param array $options CLI options
* @return void
*/
function tool_models_calculate_course_dates($course, $options) {
global $DB, $OUTPUT;
......@@ -153,7 +160,8 @@ function tool_models_calculate_course_dates($course, $options) {
if ($options['update']) {
format_weeks::update_end_date($course->id);
$course->enddate = $DB->get_field('course', 'enddate', array('id' => $course->id));
$notification .= PHP_EOL . ' ' . get_string('weeksenddateautomaticallyset', 'tool_models') . ': ' . userdate($course->enddate);
$notification .= PHP_EOL . ' ' . get_string('weeksenddateautomaticallyset', 'tool_models') . ': ' .
userdate($course->enddate);
} else {
// We can't provide more info without actually updating it in db.
$notification .= PHP_EOL . ' ' . get_string('weeksenddatedefault', 'tool_models');
......@@ -194,4 +202,6 @@ function tool_models_calculate_course_dates($course, $options) {
echo mtrace($notification);
}
echo mtrace(get_string('success'));
exit(0);
......@@ -17,11 +17,13 @@
/**
* This file defines tasks performed by the tool.
*
* @package tool_monitor
* @copyright 2014 Mark Nelson <markn@moodle.com>
* @package tool_models
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
// List of tasks.
$tasks = array(
array(
......
......@@ -24,6 +24,13 @@
defined('MOODLE_INTERNAL') || die();
/**
* Deletes models created by tool_models
*
* @package tool_models
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_tool_models_uninstall() {
global $DB;
......
......@@ -25,7 +25,7 @@
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('analyticmodels', '', null, '', array('pagelayout'=>'report'));
admin_externalpage_setup('analyticmodels', '', null, '', array('pagelayout' => 'report'));
$models = \core_analytics\manager::get_all_models();
......
......@@ -17,7 +17,7 @@
/**
* Model-related actions.
*
* @package tool_model
* @package tool_models
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
......
......@@ -15,6 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Extension to show an error message if the selected predictor is not available.
*
* @package core_analytics
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
......@@ -27,6 +28,13 @@ defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../../lib/adminlib.php');
/**
* Extension to show an error message if the selected predictor is not available.
*
* @package core_analytics
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_setting_predictor extends \admin_setting_configselect {
/**
......@@ -40,7 +48,7 @@ class admin_setting_predictor extends \admin_setting_configselect {
return '';
}
if (!array_key_exists($data, $this->choices)) {
return ''; // ignore it
return '';
}
// Calling it here without checking if it is ready because we check it below and show it as a controlled case.
......
......@@ -15,6 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Any element analysers can analyse.
*
* @package core_analytics
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
......@@ -26,6 +27,7 @@ namespace core_analytics;
defined('MOODLE_INTERNAL') || die();
/**
* Any element analysers can analyse.
*
* @package core_analytics
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
......@@ -33,13 +35,36 @@ defined('MOODLE_INTERNAL') || die();
*/
interface analysable {
/**
* Max timestamp.
*/
const MAX_TIME = 9999999999;
/**
* The analysable unique identifier in the site.
*
* @return int.
*/
public function get_id();
/**
* The analysable context.
*
* @return \context
*/
public function get_context();
/**
* The start of the analysable if there is one.
*
* @return int|false
*/
public function get_start();
/**
* The end of the analysable if there is one.
*
* @return int|false
*/
public function get_end();
}
......@@ -35,10 +35,29 @@ defined('MOODLE_INTERNAL') || die();
*/
abstract class calculable {
/**
* Neutral calculation outcome.
*/
const OUTCOME_NEUTRAL = 0;
/**
* Very positive calculation outcome.
*/
const OUTCOME_VERY_POSITIVE = 1;
/**
* Positive calculation outcome.
*/
const OUTCOME_OK = 2;
/**
* Negative calculation outcome.
*/
const OUTCOME_NEGATIVE = 3;
/**
* Very negative calculation outcome.
*/
const OUTCOME_VERY_NEGATIVE = 4;
/**
......@@ -243,7 +262,6 @@ abstract class calculable {
* Merges arrays recursively keeping the same keys the original arrays have.
*
* @link http://php.net/manual/es/function.array-merge-recursive.php#114818
* @param array
* @return array
*/
private function array_merge_recursive_keep_keys() {
......@@ -256,8 +274,8 @@ abstract class calculable {
if (is_array($value) && !empty($base[$key]) && is_array($base[$key])) {
$base[$key] = $this->array_merge_recursive_keep_keys($base[$key], $value);
} else {
if(isset($base[$key]) && is_int($key)) {
$key++;
if (isset($base[$key]) && is_int($key)) {
$key++;
}
$base[$key] = $value;
}
......
......@@ -15,6 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Moodle course analysable
*
* @package core_analytics
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
......@@ -30,6 +31,7 @@ require_once($CFG->dirroot . '/lib/gradelib.php');
require_once($CFG->dirroot . '/lib/enrollib.php');
/**
* Moodle course analysable
*
* @package core_analytics
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
......@@ -37,24 +39,81 @@ require_once($CFG->dirroot . '/lib/enrollib.php');
*/
class course implements \core_analytics\analysable {
/**
* @var \core_analytics\course[] $instances
*/
protected static $instances = array();
protected static $studentroles = [];
protected static $teacherroles = [];
/**
* Course object
*
* @var \stdClass
*/
protected $course = null;
/**
* The course context.
*
* @var \context_course
*/
protected $coursecontext = null;
/**
* The course activities organized by activity type.
*
* @var array
*/
protected $courseactivities = array();
/**
* Course start time.
*
* @var int
*/
protected $starttime = null;
/**
* Has the course already started?