Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
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_alignment(\action_menu::TL, \action_menu::BL); 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 $actionsmenu->set_alignment(\action_menu::TL, \action_menu::BL); 195 196 $urlparams = ['id' => $model->get_id(), 'sesskey' => sesskey()]; 197 198 // Get predictions. 199 if (!$onlycli && $modeldata->enabled && !empty($modeldata->timesplitting)) { 200 $urlparams['action'] = 'scheduledanalysis'; 201 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 202 $icon = new \action_menu_link_secondary($url, 203 new \pix_icon('i/notifications', get_string('executescheduledanalysis', 'tool_analytics')), 204 get_string('executescheduledanalysis', 'tool_analytics')); 205 $actionsmenu->add($icon); 206 } 207 208 // Evaluate machine-learning-based models. 209 if (!$onlycli && $model->get_indicators() && !$model->is_static()) { 210 211 // Extra is_trained call as trained_locally returns false if the model has not been trained yet. 212 $trainedonlyexternally = !$model->trained_locally() && $model->is_trained(); 213 214 $actionid = 'evaluate-' . $model->get_id(); 215 216 // Evaluation options. 217 $modeltimesplittingmethods = $this->timesplittings_options_for_evaluation($model, $timesplittingsforevaluation); 218 219 // Include the current time-splitting method as the default selection method the model already have one. 220 if ($model->get_model_obj()->timesplitting) { 221 $currenttimesplitting = ['id' => 'current', 'text' => get_string('currenttimesplitting', 'tool_analytics')]; 222 array_unshift($modeltimesplittingmethods, $currenttimesplitting); 223 } 224 225 $evaluateparams = [$actionid, $trainedonlyexternally]; 226 $PAGE->requires->js_call_amd('tool_analytics/model', 'selectEvaluationOptions', $evaluateparams); 227 $urlparams['action'] = 'evaluate'; 228 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 229 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_analytics')), 230 get_string('evaluate', 'tool_analytics'), ['data-action-id' => $actionid, 231 'data-timesplitting-methods' => json_encode($modeltimesplittingmethods)]); 232 $actionsmenu->add($icon); 233 } 234 235 // Machine-learning-based models evaluation log. 236 if (!$model->is_static() && $model->get_logs()) { 237 $urlparams['action'] = 'log'; 238 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 239 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_analytics')), 240 get_string('viewlog', 'tool_analytics')); 241 $actionsmenu->add($icon); 242 } 243 244 // Edit model. 245 $urlparams['action'] = 'edit'; 246 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 247 $icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit')); 248 $actionsmenu->add($icon); 249 250 // Enable / disable. 251 if ($model->is_enabled() || !empty($modeldata->timesplitting)) { 252 // If there is no timesplitting method set, the model can not be enabled. 253 if ($model->is_enabled()) { 254 $action = 'disable'; 255 $text = get_string('disable'); 256 $icontype = 't/block'; 257 } else { 258 $action = 'enable'; 259 $text = get_string('enable'); 260 $icontype = 'i/checked'; 261 } 262 $urlparams['action'] = $action; 263 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 264 $icon = new \action_menu_link_secondary($url, new \pix_icon($icontype, $text), $text); 265 $actionsmenu->add($icon); 266 } 267 268 // Export. 269 if (!$model->is_static()) { 270 271 $fullysetup = $model->get_indicators() && !empty($modeldata->timesplitting); 272 $istrained = $model->is_trained(); 273 274 if ($fullysetup || $istrained) { 275 276 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 277 // Clear the previous action param from the URL, we will set it in JS. 278 $url->remove_params('action'); 279 280 $actionid = 'export-' . $model->get_id(); 281 $PAGE->requires->js_call_amd('tool_analytics/model', 'selectExportOptions', 282 [$actionid, $istrained]); 283 284 $icon = new \action_menu_link_secondary($url, new \pix_icon('i/export', 285 get_string('export', 'tool_analytics')), get_string('export', 'tool_analytics'), 286 ['data-action-id' => $actionid]); 287 $actionsmenu->add($icon); 288 } 289 } 290 291 // Insights report. 292 if (!empty($anypredictionobtained) && $model->uses_insights()) { 293 $urlparams['action'] = 'insightsreport'; 294 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 295 $pix = new \pix_icon('i/report', get_string('insightsreport', 'tool_analytics')); 296 $icon = new \action_menu_link_secondary($url, $pix, get_string('insightsreport', 'tool_analytics')); 297 $actionsmenu->add($icon); 298 } 299 300 // Invalid analysables. 301 $analyser = $model->get_analyser(['notimesplitting' => true]); 302 if (!$analyser instanceof \core_analytics\local\analyser\sitewide) { 303 $urlparams['action'] = 'invalidanalysables'; 304 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 305 $pix = new \pix_icon('i/report', get_string('invalidanalysables', 'tool_analytics')); 306 $icon = new \action_menu_link_secondary($url, $pix, get_string('invalidanalysables', 'tool_analytics')); 307 $actionsmenu->add($icon); 308 } 309 310 // Clear model. 311 if (!empty($anypredictionobtained) || $model->is_trained()) { 312 $actionid = 'clear-' . $model->get_id(); 313 $PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'clear']); 314 $urlparams['action'] = 'clear'; 315 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 316 $icon = new \action_menu_link_secondary($url, new \pix_icon('e/cleanup_messy_code', 317 get_string('clearpredictions', 'tool_analytics')), get_string('clearpredictions', 'tool_analytics'), 318 ['data-action-id' => $actionid]); 319 $actionsmenu->add($icon); 320 } 321 322 // Delete model. 323 $actionid = 'delete-' . $model->get_id(); 324 $PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'delete']); 325 $urlparams['action'] = 'delete'; 326 $url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams); 327 $icon = new \action_menu_link_secondary($url, new \pix_icon('t/delete', 328 get_string('delete', 'tool_analytics')), get_string('delete', 'tool_analytics'), 329 ['data-action-id' => $actionid]); 330 $actionsmenu->add($icon); 331 332 $modeldata->actions = $actionsmenu->export_for_template($output); 333 334 $data->models[] = $modeldata; 335 } 336 337 $data->warnings = []; 338 $data->infos = []; 339 if (!$onlycli) { 340 $data->warnings[] = (object)array('message' => get_string('bettercli', 'tool_analytics'), 'closebutton' => true); 341 } else { 342 $url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'), 343 'id_s_analytics_onlycli'); 344 345 $langstrid = 'clievaluationandpredictionsnoadmin'; 346 if (is_siteadmin()) { 347 $langstrid = 'clievaluationandpredictions'; 348 } 349 $data->infos[] = (object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()), 350 'closebutton' => true); 351 } 352 353 if ($misconfiguredmodels) { 354 $warningstr = get_string('invalidtimesplittinginmodels', 'tool_analytics', implode(', ', $misconfiguredmodels)); 355 $data->warnings[] = (object)array('message' => $warningstr, 'closebutton' => true); 356 } 357 358 return $data; 359 } 360 361 /** 362 * Returns the list of time splitting methods that are available for evaluation. 363 * 364 * @param \core_analytics\model $model 365 * @param array $timesplittingsforevaluation 366 * @return array 367 */ 368 private function timesplittings_options_for_evaluation(\core_analytics\model $model, 369 array $timesplittingsforevaluation): array { 370 371 $modeltimesplittingmethods = [ 372 ['id' => 'all', 'text' => get_string('alltimesplittingmethods', 'tool_analytics')], 373 ]; 374 $potentialtimesplittingmethods = $model->get_potential_timesplittings(); 375 foreach ($timesplittingsforevaluation as $timesplitting) { 376 if (empty($potentialtimesplittingmethods[$timesplitting->get_id()])) { 377 // This time-splitting method can not be used for this model. 378 continue; 379 } 380 $modeltimesplittingmethods[] = [ 381 'id' => \tool_analytics\output\helper::class_to_option($timesplitting->get_id()), 382 'text' => $timesplitting->get_name()->out(), 383 ]; 384 } 385 386 return $modeltimesplittingmethods; 387 } 388 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body