mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
Merge branch 'MDL-59779_master' of git://github.com/dmonllao/moodle
This commit is contained in:
commit
9533cf3419
16 changed files with 158 additions and 40 deletions
|
@ -140,10 +140,18 @@ class course implements \core_analytics\analysable {
|
|||
$this->now = time();
|
||||
|
||||
// Get the course users, including users assigned to student and teacher roles at an higher context.
|
||||
$cache = \cache::make_from_params(\cache_store::MODE_REQUEST, 'core_analytics', 'rolearchetypes');
|
||||
|
||||
if (!$studentroles = $cache->get('student')) {
|
||||
$studentroles = array_keys(get_archetype_roles('student'));
|
||||
$cache->set('student', $studentroles);
|
||||
}
|
||||
$this->studentids = $this->get_user_ids($studentroles);
|
||||
|
||||
if (!$teacherroles = $cache->get('teacher')) {
|
||||
$teacherroles = array_keys(get_archetype_roles('editingteacher') + get_archetype_roles('teacher'));
|
||||
$cache->set('teacher', $teacherroles);
|
||||
}
|
||||
$this->teacherids = $this->get_user_ids($teacherroles);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,22 @@ abstract class base extends \core_analytics\calculable {
|
|||
return self::MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to allow indicators to pre-fill data that is shared accross time range calculations.
|
||||
*
|
||||
* Useful to fill analysable-dependant data that does not depend on the time ranges. Use
|
||||
* instance vars to cache data that can be re-used across samples calculations but changes
|
||||
* between time ranges (indicator instances are reset between time ranges to avoid unexpected
|
||||
* problems).
|
||||
*
|
||||
* You are also responsible of emptying previous analysable caches.
|
||||
*
|
||||
* @param \core_analytics\analysable $analysable
|
||||
* @return void
|
||||
*/
|
||||
public function fill_per_analysable_caches(\core_analytics\analysable $analysable) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the indicator.
|
||||
*
|
||||
|
|
|
@ -70,6 +70,20 @@ abstract class community_of_inquiry_activity extends linear {
|
|||
*/
|
||||
const MAX_SOCIAL_LEVEL = 5;
|
||||
|
||||
/**
|
||||
* Fetch the course grades of this activity type instances.
|
||||
*
|
||||
* @param \core_analytics\analysable $analysable
|
||||
* @return void
|
||||
*/
|
||||
public function fill_per_analysable_caches(\core_analytics\analysable $analysable) {
|
||||
|
||||
// Better to check it, we can not be 100% it will be a \core_analytics\course object.
|
||||
if ($analysable instanceof \core_analytics\course) {
|
||||
$this->fetch_student_grades($analysable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the activity type. No point in changing this class in children classes.
|
||||
*
|
||||
|
@ -406,8 +420,8 @@ abstract class community_of_inquiry_activity extends linear {
|
|||
}
|
||||
|
||||
if ($this->grades === null) {
|
||||
$courseactivities = $this->course->get_all_activities($this->get_activity_type());
|
||||
$this->grades = $this->course->get_student_grades($courseactivities);
|
||||
// Even if this is probably already filled during fill_per_analysable_caches.
|
||||
$this->fetch_student_grades($this->course);
|
||||
}
|
||||
|
||||
if ($cm = $this->retrieve('cm', $sampleid)) {
|
||||
|
@ -662,6 +676,17 @@ abstract class community_of_inquiry_activity extends linear {
|
|||
throw new \coding_exception("Indicator type is invalid.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the course student grades.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
protected function fetch_student_grades(\core_analytics\course $course) {
|
||||
$courseactivities = $course->get_all_activities($this->get_activity_type());
|
||||
$this->grades = $course->get_student_grades($courseactivities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines indicator type.
|
||||
*
|
||||
|
|
|
@ -130,6 +130,8 @@ abstract class base extends \core_analytics\calculable {
|
|||
/**
|
||||
* Callback to execute once a prediction has been returned from the predictions processor.
|
||||
*
|
||||
* Note that the analytics_predictions db record is not yet inserted.
|
||||
*
|
||||
* @param int $modelid
|
||||
* @param int $sampleid
|
||||
* @param int $rangeindex
|
||||
|
|
|
@ -235,6 +235,9 @@ abstract class base {
|
|||
$newcalculations = array();
|
||||
foreach ($indicators as $indicator) {
|
||||
|
||||
// Hook to allow indicators to store analysable-dependant data.
|
||||
$indicator->fill_per_analysable_caches($this->analysable);
|
||||
|
||||
// Per-range calculations.
|
||||
foreach ($ranges as $rangeindex => $range) {
|
||||
|
||||
|
|
|
@ -775,9 +775,12 @@ class model {
|
|||
list($sampleid, $rangeindex) = $this->get_time_splitting()->infer_sample_info($uniquesampleid);
|
||||
|
||||
// Store the predicted values.
|
||||
$samplecontext = $this->save_prediction($sampleid, $rangeindex, $prediction->prediction,
|
||||
list($record, $samplecontext) = $this->prepare_prediction_record($sampleid, $rangeindex, $prediction->prediction,
|
||||
$prediction->predictionscore, json_encode($indicatorcalculations[$uniquesampleid]));
|
||||
|
||||
// We will later bulk-insert them all.
|
||||
$records[$uniquesampleid] = $record;
|
||||
|
||||
// Also store all samples context to later generate insights or whatever action the target wants to perform.
|
||||
$samplecontexts[$samplecontext->id] = $samplecontext;
|
||||
|
||||
|
@ -786,6 +789,8 @@ class model {
|
|||
}
|
||||
}
|
||||
|
||||
$this->save_predictions($records);
|
||||
|
||||
return $samplecontexts;
|
||||
}
|
||||
|
||||
|
@ -912,7 +917,7 @@ class model {
|
|||
* @param string $calculations
|
||||
* @return \context
|
||||
*/
|
||||
protected function save_prediction($sampleid, $rangeindex, $prediction, $predictionscore, $calculations) {
|
||||
protected function prepare_prediction_record($sampleid, $rangeindex, $prediction, $predictionscore, $calculations) {
|
||||
global $DB;
|
||||
|
||||
$context = $this->get_analyser()->sample_access_context($sampleid);
|
||||
|
@ -926,9 +931,18 @@ class model {
|
|||
$record->predictionscore = $predictionscore;
|
||||
$record->calculations = $calculations;
|
||||
$record->timecreated = time();
|
||||
$DB->insert_record('analytics_predictions', $record);
|
||||
|
||||
return $context;
|
||||
return array($record, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the prediction objects.
|
||||
*
|
||||
* @param \stdClass[] $records
|
||||
*/
|
||||
protected function save_predictions($records) {
|
||||
global $DB;
|
||||
$DB->insert_records('analytics_predictions', $records);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -73,21 +73,14 @@ class site implements \core_analytics\analysable {
|
|||
return $this->start;
|
||||
}
|
||||
|
||||
if (!$logstore = \core_analytics\manager::get_analytics_logstore()) {
|
||||
$this->start = 0;
|
||||
return $this->start;
|
||||
// Much faster than reading the first log in the site.
|
||||
$admins = get_admins();
|
||||
$this->start = 9999999999;
|
||||
foreach ($admins as $admin) {
|
||||
if ($admin->firstaccess < $this->start) {
|
||||
$this->start = $admin->firstaccess;
|
||||
}
|
||||
|
||||
// Basically a SELECT MIN(timecreated) FROM ...
|
||||
$events = $logstore->get_events_select("", array(), "timecreated ASC", 0, 1);
|
||||
if ($events) {
|
||||
// There should be just 1 event.
|
||||
$event = reset($events);
|
||||
$this->start = intval($event->timecreated);
|
||||
} else {
|
||||
$this->start = 0;
|
||||
}
|
||||
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
|
@ -101,21 +94,7 @@ class site implements \core_analytics\analysable {
|
|||
return $this->end;
|
||||
}
|
||||
|
||||
if (!$logstore = \core_analytics\manager::get_analytics_logstore()) {
|
||||
$this->end = time();
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
// Basically a SELECT MAX(timecreated) FROM ...
|
||||
$events = $logstore->get_events_select("", array(), "timecreated DESC", 0, 1);
|
||||
if ($events) {
|
||||
// There should be just 1 event.
|
||||
$event = reset($events);
|
||||
$this->end = intval($event->timecreated);
|
||||
} else {
|
||||
$this->end = time();
|
||||
}
|
||||
|
||||
return $this->end;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,12 +150,11 @@ class analytics_model_testcase extends advanced_testcase {
|
|||
|
||||
global $DB;
|
||||
|
||||
// 2 built-in models + the testing one.
|
||||
$this->assertCount(3, $DB->get_records('analytics_models'));
|
||||
$count = $DB->count_records('analytics_models');
|
||||
|
||||
// No new models added if the builtin ones already exist.
|
||||
\core_analytics\manager::add_builtin_models();
|
||||
$this->assertCount(3, $DB->get_records('analytics_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));
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,4 +34,13 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
|
||||
|
||||
/**
|
||||
* No need to fetch grades for resources.
|
||||
*
|
||||
* @param \core_analytics\course $course
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_student_grades(\core_analytics\course $course) {
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue