Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403]
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 * Prediction models list page. 19 * 20 * @package tool_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 tool_analytics\output; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Shows tool_analytics models list. 31 * 32 * @package tool_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 class models_list implements \renderable, \templatable { 37 38 /** 39 * models 40 * 41 * @var \core_analytics\model[] 42 */ 43 protected $models = array(); 44 45 /** 46 * __construct 47 * 48 * @param \core_analytics\model[] $models 49 * @return void 50 */ 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) { 62 global $PAGE; 63 64 $data = new \stdClass(); 65 66 $newmodelmenu = new \action_menu(); 67 $newmodelmenu->set_menu_trigger(get_string('newmodel', 'tool_analytics'), 'btn btn-secondary'); 68 $newmodelmenu->set_menu_left(); 69 70 $newmodelmenu->add(new \action_menu_link( 71 new \moodle_url('/admin/tool/analytics/createmodel.php'), 72 new \pix_icon('i/edit', ''), 73 get_string('createmodel', 'tool_analytics'), 74 false 75 )); 76 77 $newmodelmenu->add(new \action_menu_link( 78 new \moodle_url('/admin/tool/analytics/importmodel.php'), 79 new \pix_icon('i/import', ''), 80 get_string('importmodel', 'tool_analytics'), 81 false 82 )); 83 84 $newmodelmenu->add(new \action_menu_link( 85 new \moodle_url('/admin/tool/analytics/restoredefault.php'), 86 new \pix_icon('i/reload', ''), 87 get_string('restoredefault', 'tool_analytics'), 88 false 89 )); 90 91 $data->newmodelmenu = $newmodelmenu->export_for_template($output); 92 93 $onlycli = get_config('analytics', 'onlycli'); 94 if ($onlycli === false) { 95 // Default applied if no config found. 96 $onlycli = 1; 97 } 98 99 // Evaluation options. 100 $timesplittingsforevaluation = \core_analytics\manager::get_time_splitting_methods_for_evaluation(true); 101 102 $misconfiguredmodels = []; 103 $data->models = array(); 104 foreach ($this->models as $model) { 105 $modeldata = $model->export($output); 106 107 // Check if there is a help icon for the target to show. 108 $identifier = $modeldata->target->get_identifier(); 109 $component = $modeldata->target->get_component(); 110 if (get_string_manager()->string_exists($identifier . '_help', $component)) { 111 $helpicon = new \help_icon($identifier, $component); 112 $modeldata->targethelp = $helpicon->export_for_template($output); 113 } else { 114 // We really want to encourage developers to add help to their targets. 115 debugging("The target '{$modeldata->target}' should include a '{$identifier}_help' string to 116 describe its purpose.", DEBUG_DEVELOPER); 117 } 118 119 if ($model->invalid_timesplitting_selected()) { 120 $misconfiguredmodels[$model->get_id()] = $model->get_name(); 121 } 122 123 // Check if there is a help icon for the indicators to show. 124 if (!empty($modeldata->indicators)) { 125 $indicators = array(); 126 foreach ($modeldata->indicators as $ind) { 127 // Create the indicator with the details we want for the context. 128 $indicator = new \stdClass(); 129 $indicator->name = $ind->out(); 130 $identifier = $ind->get_identifier(); 131 $component = $ind->get_component(); 132 if (get_string_manager()->string_exists($identifier . '_help', $component)) { 133 $helpicon = new \help_icon($identifier, $component); 134 $indicator->help = $helpicon->export_for_template($output); 135 } else { 136 // We really want to encourage developers to add help to their indicators. 137 debugging("The indicator '{$ind}' should include a '{$identifier}_help' string to 138 describe its purpose.", DEBUG_DEVELOPER); 139 } 140 $indicators[] = $indicator; 141 } 142 $modeldata->indicators = $indicators; 143 } 144 145 $modeldata->indicatorsnum = count($modeldata->indicators); 146 147 // Check if there is a help icon for the time splitting method. 148 if (!empty($modeldata->timesplitting)) { 149 $identifier = $modeldata->timesplitting->get_identifier(); 150 $component = $modeldata->timesplitting->get_component(); 151 if (get_string_manager()->string_exists($identifier . '_help', $component)) { 152 $helpicon = new \help_icon($identifier, $component); 153 $modeldata->timesplittinghelp = $helpicon->export_for_template($output); 154 } else { 155 // We really want to encourage developers to add help to their time splitting methods. 156 debugging("The analysis interval '{$modeldata->timesplitting}' should include a '{$identifier}_help' 157 string to describe its purpose.", DEBUG_DEVELOPER); 158 } 159 } else { 160 $helpicon = new \help_icon('timesplittingnotdefined', 'tool_analytics'); 161 $modeldata->timesplittinghelp = $helpicon->export_for_template($output); 162 } 163 164 // Has this model generated predictions?. 165 $predictioncontexts = $model->get_predictions_contexts(); 166 $anypredictionobtained = $model->any_prediction_obtained(); 167 168 // Model predictions list. 169 if (!$model->is_enabled()) { 170 $modeldata->noinsights = get_string('disabledmodel', 'analytics'); 171 } else if ($model->uses_insights()) { 172 if ($predictioncontexts) { 173 $url = new \moodle_url('/report/insights/insights.php', array('modelid' => $model->get_id())); 174 $modeldata->insights = \tool_analytics\output\helper::prediction_context_selector($predictioncontexts, 175 $url, $output); 176 } 177 178 if (empty($modeldata->insights)) { 179 if ($anypredictionobtained) { 180 $modeldata->noinsights = get_string('noinsights', 'analytics'); 181 } else { 182 $modeldata->noinsights = get_string('nopredictionsyet', 'analytics'); 183 } 184 } 185 186 } else { 187 $modeldata->noinsights = get_string('noinsightsmodel', 'analytics'); 188 } 189 190 // Actions. 191 $actionsmenu = new \action_menu(); 192 $actionsmenu->set_menu_trigger(get_string('actions')); 193 $actionsmenu->set_owner_selector('model-actions-' . $model->get_id()); 194 195 $urlparams = ['id' => $model->get_id(), 'sesskey' => sesskey()]; 196 197 // Get predictions. 198 if (!$onlycli && $modeldata->enabled && !empty($modeldata->timesplitting)) { 199 $urlparams['action'] = 'scheduledanalysis'; 200 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 201 $icon = new \action_menu_link_secondary($url, 202 new \pix_icon('i/notifications', get_string('executescheduledanalysis', 'tool_analytics')), 203 get_string('executescheduledanalysis', 'tool_analytics')); 204 $actionsmenu->add($icon); 205 } 206 207 // Evaluate machine-learning-based models. 208 if (!$onlycli && $model->get_indicators() && !$model->is_static()) { 209 210 // Extra is_trained call as trained_locally returns false if the model has not been trained yet. 211 $trainedonlyexternally = !$model->trained_locally() && $model->is_trained(); 212 213 $actionid = 'evaluate-' . $model->get_id(); 214 215 // Evaluation options. 216 $modeltimesplittingmethods = $this->timesplittings_options_for_evaluation($model, $timesplittingsforevaluation); 217 218 // Include the current time-splitting method as the default selection method the model already have one. 219 if ($model->get_model_obj()->timesplitting) { 220 $currenttimesplitting = ['id' => 'current', 'text' => get_string('currenttimesplitting', 'tool_analytics')]; 221 array_unshift($modeltimesplittingmethods, $currenttimesplitting); 222 } 223 224 $evaluateparams = [$actionid, $trainedonlyexternally]; 225 $PAGE->requires->js_call_amd('tool_analytics/model', 'selectEvaluationOptions', $evaluateparams); 226 $urlparams['action'] = 'evaluate'; 227 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 228 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_analytics')), 229 get_string('evaluate', 'tool_analytics'), ['data-action-id' => $actionid, 230 'data-timesplitting-methods' => json_encode($modeltimesplittingmethods)]); 231 $actionsmenu->add($icon); 232 } 233 234 // Machine-learning-based models evaluation log. 235 if (!$model->is_static() && $model->get_logs()) { 236 $urlparams['action'] = 'log'; 237 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 238 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_analytics')), 239 get_string('viewlog', 'tool_analytics')); 240 $actionsmenu->add($icon); 241 } 242 243 // Edit model. 244 $urlparams['action'] = 'edit'; 245 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 246 $icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit')); 247 $actionsmenu->add($icon); 248 249 // Enable / disable. 250 if ($model->is_enabled() || !empty($modeldata->timesplitting)) { 251 // If there is no timesplitting method set, the model can not be enabled. 252 if ($model->is_enabled()) { 253 $action = 'disable'; 254 $text = get_string('disable'); 255 $icontype = 't/block'; 256 } else { 257 $action = 'enable'; 258 $text = get_string('enable'); 259 $icontype = 'i/checked'; 260 } 261 $urlparams['action'] = $action; 262 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 263 $icon = new \action_menu_link_secondary($url, new \pix_icon($icontype, $text), $text); 264 $actionsmenu->add($icon); 265 } 266 267 // Export. 268 if (!$model->is_static()) { 269 270 $fullysetup = $model->get_indicators() && !empty($modeldata->timesplitting); 271 $istrained = $model->is_trained(); 272 273 if ($fullysetup || $istrained) { 274 275 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 276 // Clear the previous action param from the URL, we will set it in JS. 277 $url->remove_params('action'); 278 279 $actionid = 'export-' . $model->get_id(); 280 $PAGE->requires->js_call_amd('tool_analytics/model', 'selectExportOptions', 281 [$actionid, $istrained]); 282 283 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/export', 284 get_string('export', 'tool_analytics')), get_string('export', 'tool_analytics'), 285 ['data-action-id' => $actionid]); 286 $actionsmenu->add($icon); 287 } 288 } 289 290 // Insights report. 291 if (!empty($anypredictionobtained) && $model->uses_insights()) { 292 $urlparams['action'] = 'insightsreport'; 293 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 294 $pix = new \pix_icon('i/report', get_string('insightsreport', 'tool_analytics')); 295 $icon = new \action_menu_link_secondary($url, $pix, get_string('insightsreport', 'tool_analytics')); 296 $actionsmenu->add($icon); 297 } 298 299 // Invalid analysables. 300 $analyser = $model->get_analyser(['notimesplitting' => true]); 301 if (!$analyser instanceof \core_analytics\local\analyser\sitewide) { 302 $urlparams['action'] = 'invalidanalysables'; 303 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 304 $pix = new \pix_icon('i/report', get_string('invalidanalysables', 'tool_analytics')); 305 $icon = new \action_menu_link_secondary($url, $pix, get_string('invalidanalysables', 'tool_analytics')); 306 $actionsmenu->add($icon); 307 } 308 309 // Clear model. 310 if (!empty($anypredictionobtained) || $model->is_trained()) { 311 $actionid = 'clear-' . $model->get_id(); 312 $PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'clear']); 313 $urlparams['action'] = 'clear'; 314 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 315 $icon = new \action_menu_link_secondary($url, new \pix_icon('e/cleanup_messy_code', 316 get_string('clearpredictions', 'tool_analytics')), get_string('clearpredictions', 'tool_analytics'), 317 ['data-action-id' => $actionid]); 318 $actionsmenu->add($icon); 319 } 320 321 // Delete model. 322 $actionid = 'delete-' . $model->get_id(); 323 $PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'delete']); 324 $urlparams['action'] = 'delete'; 325 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 326 $icon = new \action_menu_link_secondary($url, new \pix_icon('t/delete', 327 get_string('delete', 'tool_analytics')), get_string('delete', 'tool_analytics'), 328 ['data-action-id' => $actionid]); 329 $actionsmenu->add($icon); 330 331 $modeldata->actions = $actionsmenu->export_for_template($output); 332 333 $data->models[] = $modeldata; 334 } 335 336 $data->warnings = []; 337 $data->infos = []; 338 if (!$onlycli) { 339 $data->warnings[] = (object)array('message' => get_string('bettercli', 'tool_analytics'), 'closebutton' => true); 340 } else { 341 $url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'), 342 'id_s_analytics_onlycli'); 343 344 $langstrid = 'clievaluationandpredictionsnoadmin'; 345 if (is_siteadmin()) { 346 $langstrid = 'clievaluationandpredictions'; 347 } 348 $data->infos[] = (object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()), 349 'closebutton' => true); 350 } 351 352 if ($misconfiguredmodels) { 353 $warningstr = get_string('invalidtimesplittinginmodels', 'tool_analytics', implode(', ', $misconfiguredmodels)); 354 $data->warnings[] = (object)array('message' => $warningstr, 'closebutton' => true); 355 } 356 357 return $data; 358 } 359 360 /** 361 * Returns the list of time splitting methods that are available for evaluation. 362 * 363 * @param \core_analytics\model $model 364 * @param array $timesplittingsforevaluation 365 * @return array 366 */ 367 private function timesplittings_options_for_evaluation(\core_analytics\model $model, 368 array $timesplittingsforevaluation): array { 369 370 $modeltimesplittingmethods = [ 371 ['id' => 'all', 'text' => get_string('alltimesplittingmethods', 'tool_analytics')], 372 ]; 373 $potentialtimesplittingmethods = $model->get_potential_timesplittings(); 374 foreach ($timesplittingsforevaluation as $timesplitting) { 375 if (empty($potentialtimesplittingmethods[$timesplitting->get_id()])) { 376 // This time-splitting method can not be used for this model. 377 continue; 378 } 379 $modeltimesplittingmethods[] = [ 380 'id' => \tool_analytics\output\helper::class_to_option($timesplitting->get_id()), 381 'text' => $timesplitting->get_name()->out(), 382 ]; 383 } 384 385 return $modeltimesplittingmethods; 386 } 387 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body