. /** * Abstract base indicator. * * @package core_analytics * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_analytics\local\indicator; defined('MOODLE_INTERNAL') || die(); /** * Abstract base indicator. * * @package core_analytics * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class base extends \core_analytics\calculable { /** * Min value an indicator can return. */ const MIN_VALUE = -1; /** * Max value an indicator can return. */ const MAX_VALUE = 1; /** * Converts the calculated indicators to dataset feature/s. * * @param float|int[] $calculatedvalues * @return array */ abstract protected function to_features($calculatedvalues); /** * Calculates the sample. * * Return a value from self::MIN_VALUE to self::MAX_VALUE or null if the indicator can not be calculated for this sample. * * @param int $sampleid * @param string $sampleorigin * @param integer $starttime Limit the calculation to this timestart * @param integer $endtime Limit the calculation to this timeend * @return float|null */ abstract protected function calculate_sample($sampleid, $sampleorigin, $starttime, $endtime); /** * Should this value be displayed? * * Indicators providing multiple features can be used this method to discard some of them. * * @param float $value * @param string $subtype * @return bool */ public function should_be_displayed($value, $subtype) { // We should everything by default. return true; } /** * Allows indicators to specify data they need. * * e.g. A model using courses as samples will not provide users data, but an indicator like * "user is hungry" needs user data. * * @return null|string[] Name of the required elements (use the database tablename) */ public static function required_sample_data() { return null; } /** * Returns an instance of the indicator. * * Useful to reset cached data. * * @return \core_analytics\local\indicator\base */ public static function instance() { return new static(); } /** * Returns the maximum value an indicator calculation can return. * * @return float */ public static function get_max_value() { return self::MAX_VALUE; } /** * Returns the minimum value an indicator calculation can return. * * @return float */ public static function get_min_value() { return self::MIN_VALUE; } /** * Calculates the indicator. * * Returns an array of values which size matches $sampleids size. * * @param int[] $sampleids * @param string $samplesorigin * @param integer $starttime Limit the calculation to this timestart * @param integer $endtime Limit the calculation to this timeend * @return array The format to follow is [userid] = int|float[] */ public function calculate($sampleids, $samplesorigin, $starttime = false, $endtime = false) { if (!PHPUNIT_TEST && CLI_SCRIPT) { echo '.'; } $calculations = array(); foreach ($sampleids as $sampleid => $unusedsampleid) { $calculatedvalue = $this->calculate_sample($sampleid, $samplesorigin, $starttime, $endtime); if (!is_null($calculatedvalue) && ($calculatedvalue > self::MAX_VALUE || $calculatedvalue < self::MIN_VALUE)) { throw new \coding_exception('Calculated values should be higher than ' . self::MIN_VALUE . ' and lower than ' . self::MAX_VALUE . ' ' . $calculatedvalue . ' received'); } $calculations[$sampleid] = $calculatedvalue; } $calculations = $this->to_features($calculations); return $calculations; } }