1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Abstract base indicator. 19 * 20 * @package core_analytics 21 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core_analytics\local\indicator; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Abstract base indicator. 31 * 32 * @package core_analytics 33 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 */ 36 abstract class base extends \core_analytics\calculable { 37 38 /** 39 * Min value an indicator can return. 40 */ 41 const MIN_VALUE = -1; 42 43 /** 44 * Max value an indicator can return. 45 */ 46 const MAX_VALUE = 1; 47 48 /** 49 * Converts the calculated indicators to dataset feature/s. 50 * 51 * @param float|int[] $calculatedvalues 52 * @return array 53 */ 54 abstract protected function to_features($calculatedvalues); 55 56 /** 57 * Calculates the sample. 58 * 59 * Return a value from self::MIN_VALUE to self::MAX_VALUE or null if the indicator can not be calculated for this sample. 60 * 61 * @param int $sampleid 62 * @param string $sampleorigin 63 * @param integer $starttime Limit the calculation to this timestart 64 * @param integer $endtime Limit the calculation to this timeend 65 * @return float|null 66 */ 67 abstract protected function calculate_sample($sampleid, $sampleorigin, $starttime, $endtime); 68 69 /** 70 * Should this value be displayed? 71 * 72 * Indicators providing multiple features can be used this method to discard some of them. 73 * 74 * @param float $value 75 * @param string $subtype 76 * @return bool 77 */ 78 public function should_be_displayed($value, $subtype) { 79 // We should everything by default. 80 return true; 81 } 82 83 /** 84 * Allows indicators to specify data they need. 85 * 86 * e.g. A model using courses as samples will not provide users data, but an indicator like 87 * "user is hungry" needs user data. 88 * 89 * @return null|string[] Name of the required elements (use the database tablename) 90 */ 91 public static function required_sample_data() { 92 return null; 93 } 94 95 /** 96 * Returns an instance of the indicator. 97 * 98 * Useful to reset cached data. 99 * 100 * @return \core_analytics\local\indicator\base 101 */ 102 public static function instance() { 103 return new static(); 104 } 105 106 /** 107 * Returns the maximum value an indicator calculation can return. 108 * 109 * @return float 110 */ 111 public static function get_max_value() { 112 return self::MAX_VALUE; 113 } 114 115 /** 116 * Returns the minimum value an indicator calculation can return. 117 * 118 * @return float 119 */ 120 public static function get_min_value() { 121 return self::MIN_VALUE; 122 } 123 124 /** 125 * Hook to allow indicators to pre-fill data that is shared accross time range calculations. 126 * 127 * Useful to fill analysable-dependant data that does not depend on the time ranges. Use 128 * instance vars to cache data that can be re-used across samples calculations but changes 129 * between time ranges (indicator instances are reset between time ranges to avoid unexpected 130 * problems). 131 * 132 * You are also responsible of emptying previous analysable caches. 133 * 134 * @param \core_analytics\analysable $analysable 135 * @return void 136 */ 137 public function fill_per_analysable_caches(\core_analytics\analysable $analysable) { 138 } 139 140 /** 141 * Calculates the indicator. 142 * 143 * Returns an array of values which size matches $sampleids size. 144 * 145 * @param int[] $sampleids 146 * @param string $samplesorigin 147 * @param integer $starttime Limit the calculation to this timestart 148 * @param integer $endtime Limit the calculation to this timeend 149 * @param array $existingcalculations Existing calculations of this indicator, indexed by sampleid. 150 * @return array [0] = [$sampleid => int[]|float[]], [1] = [$sampleid => int|float], [2] = [$sampleid => $sampleid] 151 */ 152 public function calculate($sampleids, $samplesorigin, $starttime = false, $endtime = false, $existingcalculations = array()) { 153 154 if (!PHPUNIT_TEST && CLI_SCRIPT) { 155 echo '.'; 156 } 157 158 $calculations = array(); 159 $newcalculations = array(); 160 $notnulls = array(); 161 foreach ($sampleids as $sampleid => $unusedsampleid) { 162 163 if (isset($existingcalculations[$sampleid])) { 164 $calculatedvalue = $existingcalculations[$sampleid]; 165 } else { 166 $calculatedvalue = $this->calculate_sample($sampleid, $samplesorigin, $starttime, $endtime); 167 $newcalculations[$sampleid] = $calculatedvalue; 168 } 169 170 if (!is_null($calculatedvalue)) { 171 $notnulls[$sampleid] = $sampleid; 172 $this->validate_calculated_value($calculatedvalue); 173 } 174 175 $calculations[$sampleid] = $calculatedvalue; 176 } 177 178 $features = $this->to_features($calculations); 179 180 return array($features, $newcalculations, $notnulls); 181 } 182 183 /** 184 * Validates the calculated value. 185 * 186 * @throws \coding_exception 187 * @param float $calculatedvalue 188 * @return true 189 */ 190 protected function validate_calculated_value($calculatedvalue) { 191 if ($calculatedvalue > self::MAX_VALUE || $calculatedvalue < self::MIN_VALUE) { 192 throw new \coding_exception('Calculated values should be higher than ' . self::MIN_VALUE . 193 ' and lower than ' . self::MAX_VALUE . ' ' . $calculatedvalue . ' received'); 194 } 195 return true; 196 } 197 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body