2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Representation of a prediction.
20 * @package core_analytics
21 * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core_analytics
;
27 defined('MOODLE_INTERNAL') ||
die();
30 * Representation of a prediction.
32 * @package core_analytics
33 * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 * Prediction details (one of the default prediction actions)
41 const ACTION_PREDICTION_DETAILS
= 'predictiondetails';
44 * Prediction useful (one of the default prediction actions)
46 const ACTION_USEFUL
= 'useful';
49 * Prediction not useful (one of the default prediction actions)
51 const ACTION_NOT_USEFUL
= 'notuseful';
54 * Prediction already fixed (one of the default prediction actions)
56 const ACTION_FIXED
= 'fixed';
59 * Prediction not applicable.
61 const ACTION_NOT_APPLICABLE
= 'notapplicable';
64 * Prediction incorrectly flagged.
66 const ACTION_INCORRECTLY_FLAGGED
= 'incorrectlyflagged';
81 private $calculations = array();
86 * @param \stdClass|int $prediction
87 * @param array $sampledata
90 public function __construct($prediction, $sampledata) {
93 if (is_scalar($prediction)) {
94 $prediction = $DB->get_record('analytics_predictions', array('id' => $prediction), '*', MUST_EXIST
);
96 $this->prediction
= $prediction;
98 $this->sampledata
= $sampledata;
100 $this->format_calculations();
104 * Get prediction object data.
108 public function get_prediction_data() {
109 return $this->prediction
;
113 * Get prediction sample data.
117 public function get_sample_data() {
118 return $this->sampledata
;
122 * Gets the prediction calculations
126 public function get_calculations() {
127 return $this->calculations
;
131 * Stores the executed action.
133 * Prediction instances should be retrieved using \core_analytics\manager::get_prediction,
134 * It is the caller responsability to check that the user can see the prediction.
136 * @param string $actionname
137 * @param \core_analytics\local\target\base $target
139 public function action_executed($actionname, \core_analytics\local\target\base
$target) {
142 $context = \context
::instance_by_id($this->get_prediction_data()->contextid
, IGNORE_MISSING
);
144 throw new \
moodle_exception('errorpredictioncontextnotavailable', 'analytics');
147 // Check that the provided action exists.
148 $actions = $target->prediction_actions($this, true);
149 foreach ($actions as $action) {
150 if ($action->get_action_name() === $actionname) {
154 $bulkactions = $target->bulk_actions([$this]);
155 foreach ($bulkactions as $action) {
156 if ($action->get_action_name() === $actionname) {
161 throw new \
moodle_exception('errorunknownaction', 'analytics');
164 $predictionid = $this->get_prediction_data()->id
;
166 $action = new \
stdClass();
167 $action->predictionid
= $predictionid;
168 $action->userid
= $USER->id
;
169 $action->actionname
= $actionname;
170 $action->timecreated
= time();
171 $DB->insert_record('analytics_prediction_actions', $action);
174 'context' => $context,
175 'objectid' => $predictionid,
176 'other' => array('actionname' => $actionname)
178 \core\event\prediction_action_started
::create($eventdata)->trigger();
182 * format_calculations
184 * @return \stdClass[]
186 private function format_calculations() {
188 $calculations = json_decode($this->prediction
->calculations
, true);
190 foreach ($calculations as $featurename => $value) {
192 list($indicatorclass, $subtype) = $this->parse_feature_name($featurename);
194 if ($indicatorclass === 'range') {
195 // Time range indicators don't belong to any indicator class, we don't store them.
197 } else if (!\core_analytics\manager
::is_valid($indicatorclass, '\core_analytics\local\indicator\base')) {
198 throw new \
moodle_exception('errorpredictionformat', 'analytics');
201 $this->calculations
[$featurename] = new \
stdClass();
202 $this->calculations
[$featurename]->subtype
= $subtype;
203 $this->calculations
[$featurename]->indicator
= \core_analytics\manager
::get_indicator($indicatorclass);
204 $this->calculations
[$featurename]->value
= $value;
211 * @param string $featurename
214 private function parse_feature_name($featurename) {
216 $indicatorclass = $featurename;
219 // Some indicator result in more than 1 feature, we need to see which feature are we dealing with.
220 $separatorpos = strpos($featurename, '/');
221 if ($separatorpos !== false) {
222 $subtype = substr($featurename, ($separatorpos +
1));
223 $indicatorclass = substr($featurename, 0, $separatorpos);
226 return array($indicatorclass, $subtype);