Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?php
// This file is part of Moodle - http://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/>.

/**
 * Any access indicator.
 *
 * @package   core
 * @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

namespace core\analytics\indicator;

defined('MOODLE_INTERNAL') || die();

/**
 * Any access indicator.
 *
 * @package   core
 * @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class any_course_access extends \core_analytics\local\indicator\binary {

> /** @var array user last access. */ /** > protected $lastaccesses = []; * Returns the name. >
* * If there is a corresponding '_help' string this will be shown as well. * * @return \lang_string */ public static function get_name() : \lang_string { return new \lang_string('indicator:anycourseaccess'); } /** * required_sample_data * * @return string[] */ public static function required_sample_data() { return array('course', 'user'); } /** * Store userid => timeaccess relation if the provided analysable is a course. * * @param \core_analytics\analysable $analysable * @return null */ public function fill_per_analysable_caches(\core_analytics\analysable $analysable) { global $DB; if ($analysable instanceof \core_analytics\course) { // Indexed by userid (there is a UNIQUE KEY at DB level). $this->lastaccesses = $DB->get_records('user_lastaccess', ['courseid' => $analysable->get_id()], '', 'userid, timeaccess'); } } /** * calculate_sample * * @param int $sampleid * @param string $sampleorigin * @param int $starttime * @param int $endtime * @return float */ protected function calculate_sample($sampleid, $sampleorigin, $starttime = false, $endtime = false) { $course = $this->retrieve('course', $sampleid); $user = $this->retrieve('user', $sampleid); // We first try using user_lastaccess as it is much faster than the log table. if (empty($this->lastaccesses[$user->id]->timeaccess)) { // The user never accessed. return self::get_min_value(); } else if (!$starttime && !$endtime) { // No time restrictions, so all good as long as there is a record. return self::get_max_value(); } else if ($starttime && $this->lastaccesses[$user->id]->timeaccess < $starttime) { // The last access is prior to $starttime. return self::get_min_value(); } else if ($endtime && $this->lastaccesses[$user->id]->timeaccess < $endtime) { // The last access is before the $endtime. return self::get_max_value(); } else if ($starttime && !$endtime && $starttime <= $this->lastaccesses[$user->id]->timeaccess) { // No end time, so max value as long as the last access is after $starttime. return self::get_max_value(); } // If the last access is after $endtime we can not know for sure if the user accessed or not // between $starttime and $endtime, we need to check the logs table in this case. Note that // it is unlikely that we will reach this point as this indicator will be used in models whose // dates are in the past. if (!$logstore = \core_analytics\manager::get_analytics_logstore()) { throw new \coding_exception('No available log stores'); } // Filter by context to use the logstore_standard_log db table index. $select = "userid = :userid AND courseid = :courseid"; $params = ['courseid' => $course->id, 'userid' => $user->id]; if ($starttime) { $select .= " AND timecreated > :starttime"; $params['starttime'] = $starttime; } if ($endtime) { $select .= " AND timecreated <= :endtime"; $params['endtime'] = $endtime; } $nlogs = $logstore->get_events_select_count($select, $params); if ($nlogs) { return self::get_max_value(); } else { return self::get_min_value(); } } }