MDL-64679 tool_analytics: Allow trained models to be cleared
[moodle.git] / admin / tool / analytics / classes / output / models_list.php
CommitLineData
efaf8534
DM
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/**
b94dbb55 18 * Prediction models list page.
efaf8534 19 *
e10b29ed 20 * @package tool_analytics
efaf8534
DM
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
e10b29ed 25namespace tool_analytics\output;
efaf8534
DM
26
27defined('MOODLE_INTERNAL') || die();
28
29/**
e10b29ed 30 * Shows tool_analytics models list.
efaf8534 31 *
e10b29ed 32 * @package tool_analytics
efaf8534
DM
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 */
36class models_list implements \renderable, \templatable {
37
413f19bc
DM
38 /**
39 * models
40 *
41 * @var \core_analytics\model[]
42 */
efaf8534
DM
43 protected $models = array();
44
413f19bc
DM
45 /**
46 * __construct
47 *
48 * @param \core_analytics\model[] $models
49 * @return void
50 */
efaf8534
DM
51 public function __construct($models) {
52 $this->models = $models;
53 }
54
55 /**
56 * Exports the data.
57 *
58 * @param \renderer_base $output
59 * @return \stdClass
60 */
61 public function export_for_template(\renderer_base $output) {
8816022d 62 global $PAGE;
efaf8534
DM
63
64 $data = new \stdClass();
65
f19719c1
DM
66 $onlycli = get_config('analytics', 'onlycli');
67 if ($onlycli === false) {
68 // Default applied if no config found.
69 $onlycli = 1;
70 }
71
efaf8534
DM
72 $data->models = array();
73 foreach ($this->models as $model) {
74 $modeldata = $model->export();
75
2fa1f92a
MN
76 // Check if there is a help icon for the target to show.
77 $identifier = $modeldata->target->get_identifier();
78 $component = $modeldata->target->get_component();
79 if (get_string_manager()->string_exists($identifier . '_help', $component)) {
80 $helpicon = new \help_icon($identifier, $component);
81 $modeldata->targethelp = $helpicon->export_for_template($output);
82 } else {
83 // We really want to encourage developers to add help to their targets.
84 debugging("The target '{$modeldata->target}' should include a '{$identifier}_help' string to
85 describe its purpose.", DEBUG_DEVELOPER);
86 }
87
88 // Check if there is a help icon for the indicators to show.
89 if (!empty($modeldata->indicators)) {
90 $indicators = array();
91 foreach ($modeldata->indicators as $ind) {
92 // Create the indicator with the details we want for the context.
93 $indicator = new \stdClass();
94 $indicator->name = $ind->out();
95 $identifier = $ind->get_identifier();
96 $component = $ind->get_component();
97 if (get_string_manager()->string_exists($identifier . '_help', $component)) {
98 $helpicon = new \help_icon($identifier, $component);
99 $indicator->help = $helpicon->export_for_template($output);
100 } else {
101 // We really want to encourage developers to add help to their indicators.
102 debugging("The indicator '{$ind}' should include a '{$identifier}_help' string to
103 describe its purpose.", DEBUG_DEVELOPER);
104 }
105 $indicators[] = $indicator;
106 }
107 $modeldata->indicators = $indicators;
108 }
109
110 // Check if there is a help icon for the time splitting method.
111 if (!empty($modeldata->timesplitting)) {
112 $identifier = $modeldata->timesplitting->get_identifier();
113 $component = $modeldata->timesplitting->get_component();
114 if (get_string_manager()->string_exists($identifier . '_help', $component)) {
115 $helpicon = new \help_icon($identifier, $component);
116 $modeldata->timesplittinghelp = $helpicon->export_for_template($output);
117 } else {
118 // We really want to encourage developers to add help to their time splitting methods.
2f3e1760 119 debugging("The time splitting method '{$modeldata->timesplitting}' should include a '{$identifier}_help'
2fa1f92a
MN
120 string to describe its purpose.", DEBUG_DEVELOPER);
121 }
8d6b7f0c
AA
122 } else {
123 $helpicon = new \help_icon('timesplittingnotdefined', 'tool_analytics');
124 $modeldata->timesplittinghelp = $helpicon->export_for_template($output);
2fa1f92a
MN
125 }
126
8816022d
DM
127 // Has this model generated predictions?.
128 $predictioncontexts = $model->get_predictions_contexts();
129
efaf8534 130 // Model predictions list.
3e0f33aa
DM
131 if (!$model->is_enabled()) {
132 $modeldata->noinsights = get_string('disabledmodel', 'analytics');
133 } else if ($model->uses_insights()) {
f9e7447f
DM
134 if ($predictioncontexts) {
135
136 foreach ($predictioncontexts as $contextid => $unused) {
137 // We prepare this to be used as single_select template options.
138 $context = \context::instance_by_id($contextid);
f9e7447f
DM
139
140 // Special name for system level predictions as showing "System is not visually nice".
141 if ($contextid == SYSCONTEXTID) {
e10b29ed 142 $contextname = get_string('allpredictions', 'tool_analytics');
f9e7447f
DM
143 } else {
144 $contextname = shorten_text($context->get_context_name(true, true), 90);
145 }
146 $predictioncontexts[$contextid] = $contextname;
147 }
148 \core_collator::asort($predictioncontexts);
149
150 if (!empty($predictioncontexts)) {
151 $url = new \moodle_url('/report/insights/insights.php', array('modelid' => $model->get_id()));
152 $singleselect = new \single_select($url, 'contextid', $predictioncontexts);
153 $modeldata->insights = $singleselect->export_for_template($output);
efaf8534 154 }
efaf8534 155 }
efaf8534 156
f9e7447f
DM
157 if (empty($modeldata->insights)) {
158 if ($model->any_prediction_obtained()) {
159 $modeldata->noinsights = get_string('noinsights', 'analytics');
160 } else {
161 $modeldata->noinsights = get_string('nopredictionsyet', 'analytics');
162 }
efaf8534 163 }
f9e7447f
DM
164
165 } else {
166 $modeldata->noinsights = get_string('noinsightsmodel', 'analytics');
efaf8534
DM
167 }
168
169 // Actions.
170 $actionsmenu = new \action_menu();
357507b4 171 $actionsmenu->set_menu_trigger(get_string('actions'));
efaf8534
DM
172 $actionsmenu->set_owner_selector('model-actions-' . $model->get_id());
173 $actionsmenu->set_alignment(\action_menu::TL, \action_menu::BL);
174
8816022d
DM
175 $urlparams = ['id' => $model->get_id(), 'sesskey' => sesskey()];
176
177 // Get predictions.
178 if (!$onlycli && $modeldata->enabled && !empty($modeldata->timesplitting)) {
179 $urlparams['action'] = 'getpredictions';
180 $url = new \moodle_url('model.php', $urlparams);
181 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/notifications',
182 get_string('getpredictions', 'tool_analytics')), get_string('getpredictions', 'tool_analytics'));
183 $actionsmenu->add($icon);
184 }
185
186 // Evaluate machine-learning-based models.
187 if (!$onlycli && $model->get_indicators() && !$model->is_static()) {
188 $urlparams['action'] = 'evaluate';
189 $url = new \moodle_url('model.php', $urlparams);
190 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_analytics')),
191 get_string('evaluate', 'tool_analytics'));
192 $actionsmenu->add($icon);
193 }
194
195 // Machine-learning-based models evaluation log.
196 if (!$model->is_static()) {
197 $urlparams['action'] = 'log';
198 $url = new \moodle_url('model.php', $urlparams);
199 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_analytics')),
200 get_string('viewlog', 'tool_analytics'));
201 $actionsmenu->add($icon);
202 }
203
efaf8534 204 // Edit model.
357507b4 205 if (!$model->is_static()) {
8816022d
DM
206 $urlparams['action'] = 'edit';
207 $url = new \moodle_url('model.php', $urlparams);
357507b4
DM
208 $icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit'));
209 $actionsmenu->add($icon);
210 }
efaf8534 211
5c140ac4 212 // Enable / disable.
8d6b7f0c
AA
213 if ($model->is_enabled() || !empty($modeldata->timesplitting)) {
214 // If there is no timesplitting method set, the model can not be enabled.
215 if ($model->is_enabled()) {
216 $action = 'disable';
217 $text = get_string('disable');
218 $icontype = 't/block';
219 } else {
220 $action = 'enable';
221 $text = get_string('enable');
222 $icontype = 'i/checked';
223 }
224 $urlparams['action'] = $action;
225 $url = new \moodle_url('model.php', $urlparams);
226 $icon = new \action_menu_link_secondary($url, new \pix_icon($icontype, $text), $text);
227 $actionsmenu->add($icon);
5c140ac4 228 }
5c140ac4 229
d126f838
DM
230 // Export training data.
231 if (!$model->is_static() && $model->is_trained()) {
8816022d
DM
232 $urlparams['action'] = 'export';
233 $url = new \moodle_url('model.php', $urlparams);
d126f838
DM
234 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/export',
235 get_string('exporttrainingdata', 'tool_analytics')), get_string('export', 'tool_analytics'));
236 $actionsmenu->add($icon);
237 }
238
019ad9c7 239 // Invalid analysables.
71339af8 240 $analyser = $model->get_analyser(['notimesplitting' => true]);
019ad9c7
DM
241 if (!$analyser instanceof \core_analytics\local\analyser\sitewide) {
242 $urlparams['action'] = 'invalidanalysables';
243 $url = new \moodle_url('model.php', $urlparams);
244 $pix = new \pix_icon('i/report', get_string('invalidanalysables', 'tool_analytics'));
245 $icon = new \action_menu_link_secondary($url, $pix, get_string('invalidanalysables', 'tool_analytics'));
246 $actionsmenu->add($icon);
247 }
248
8816022d 249 // Clear model.
e40af65c 250 if (!empty($predictioncontexts) || $model->is_trained()) {
8816022d
DM
251 $actionid = 'clear-' . $model->get_id();
252 $PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'clear']);
253 $urlparams['action'] = 'clear';
254 $url = new \moodle_url('model.php', $urlparams);
255 $icon = new \action_menu_link_secondary($url, new \pix_icon('e/cleanup_messy_code',
256 get_string('clearpredictions', 'tool_analytics')), get_string('clearpredictions', 'tool_analytics'),
257 ['data-action-id' => $actionid]);
258 $actionsmenu->add($icon);
259 }
260
efaf8534
DM
261 $modeldata->actions = $actionsmenu->export_for_template($output);
262
263 $data->models[] = $modeldata;
264 }
265
f19719c1
DM
266 if (!$onlycli) {
267 $data->warnings = array(
268 (object)array('message' => get_string('bettercli', 'tool_analytics'), 'closebutton' => true)
269 );
270 } else {
271 $url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'),
272 'id_s_analytics_onlycli');
5da02016
DM
273
274 $langstrid = 'clievaluationandpredictionsnoadmin';
275 if (is_siteadmin()) {
276 $langstrid = 'clievaluationandpredictions';
277 }
f19719c1 278 $data->infos = array(
5da02016 279 (object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()),
f19719c1
DM
280 'closebutton' => true)
281 );
282 }
efaf8534
DM
283
284 return $data;
285 }
286}