Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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   * Insights report renderable.
  19   *
  20   * @package    tool_analytics
  21   * @copyright  2019 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   * Insights report renderable.
  31   *
  32   * @package    tool_analytics
  33   * @copyright  2019 David Monllao {@link http://www.davidmonllao.com}
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class insights_report implements \renderable, \templatable {
  37  
  38      /**
  39       * @var \core_analytics\model
  40       */
  41      private $model = null;
  42  
  43      /**
  44       * @var \context
  45       */
  46      private $context = null;
  47  
  48      /**
  49       * Inits the insights report renderable.
  50       *
  51       * @param \core_analytics\model $model
  52       * @param int|null $contextid
  53       * @return null
  54       */
  55      public function __construct(\core_analytics\model $model, ?int $contextid = null) {
  56          $this->model = $model;
  57          if ($contextid) {
  58              $this->context = \context::instance_by_id($contextid);
  59          }
  60      }
  61  
  62      /**
  63       * Export the data.
  64       *
  65       * @param \renderer_base $output
  66       * @return \stdClass
  67       */
  68      public function export_for_template(\renderer_base $output): \stdClass {
  69  
  70          // Prepare the context object.
  71          $data = new \stdClass();
  72          $data->modelname = $this->model->get_name();
  73  
  74          $data->charts = [];
  75  
  76          $predictionactionrecords = $this->model->get_prediction_actions($this->context);
  77  
  78          // Context selector.
  79          $predictioncontexts = $this->model->get_predictions_contexts(false);
  80          if ($predictioncontexts && count($predictioncontexts) > 1) {
  81              $url = new \moodle_url('/admin/tool/analytics/model.php', ['id' => $this->model->get_id(),
  82                  'action' => 'insightsreport']);
  83  
  84              if ($this->context) {
  85                  $selected = $this->context->id;
  86              } else {
  87                  // This is the 'all' option.
  88                  $selected = 0;
  89              }
  90              $data->contextselect = \tool_analytics\output\helper::prediction_context_selector($predictioncontexts,
  91                  $url, $output, $selected, true, false);
  92          }
  93  
  94          if ($predictionactionrecords->valid()) {
  95  
  96              foreach ($predictionactionrecords as $record) {
  97  
  98                  // Using this unusual execution flow to init the chart data because $predictionactionrecords
  99                  // is a \moodle_recordset.
 100                  if (empty($actionlabels)) {
 101                      list($actionlabels, $actionvalues, $actiontypes) = $this->init_action_labels($record);
 102                  }
 103  
 104                  // One value for each action.
 105                  $actionvalues['separated'][$record->actionname]++;
 106  
 107                  // Grouped value.
 108                  $actiontype = $actiontypes[$record->actionname];
 109                  $actionvalues['grouped'][$actiontype]++;
 110              }
 111              $predictionactionrecords->close();
 112  
 113              // Actions doughtnut.
 114              $chart = new \core\chart_pie();
 115              $chart->set_doughnut(true);
 116              $chart->set_title(get_string('actionsexecutedbyusers', 'tool_analytics'));
 117              $series = new \core\chart_series(get_string('actions', 'tool_analytics'),
 118                  array_values($actionvalues['separated']));
 119              $chart->add_series($series);
 120              $chart->set_labels(array_values($actionlabels['separated']));
 121              $data->separatedchart = $output->render($chart);
 122  
 123              // Positive/negative/neutral bar chart.
 124              $chart = new \core\chart_bar();
 125              $chart->set_title(get_string('actionexecutedgroupedusefulness', 'tool_analytics'));
 126              $series = new \core\chart_series(get_string('actions', 'tool_analytics'),
 127                  array_values($actionvalues['grouped']));
 128              $chart->add_series($series);
 129              $chart->set_labels(array_values($actionlabels['grouped']));
 130              $data->groupedchart = $output->render($chart);
 131  
 132          } else {
 133              $predictionactionrecords->close();
 134              $data->noactions = [
 135                  'message' => get_string('noactionsfound', 'tool_analytics'),
 136                  'announce' => true,
 137              ];
 138          }
 139          return $data;
 140      }
 141  
 142      /**
 143       * Initialises the action labels and values in this model.
 144       *
 145       * @param  \stdClass $predictionactionrecord
 146       * @return array Two-dimensional array with the labels and values initialised to zero.
 147       */
 148      private function init_action_labels(\stdClass $predictionactionrecord): array {
 149  
 150          $predictioncontext = \context::instance_by_id($predictionactionrecord->contextid);
 151  
 152          // Just 1 result, we just want to retrieve the prediction action names.
 153          list ($unused, $predictions) = $this->model->get_predictions($predictioncontext, false, 0, 1);
 154  
 155          // We pass 'true' for $isinsightuser so all the prediction actions available for this target are returning.
 156          $predictionactions = $this->model->get_target()->prediction_actions(reset($predictions), true, true);
 157  
 158          $actionlabels = [];
 159          $actionvalues = ['separated' => [], 'grouped' => []];
 160          $actiontypes = [];
 161          foreach ($predictionactions as $action) {
 162              $actionlabels['separated'][$action->get_action_name()] = $action->get_text();
 163              $actionvalues['separated'][$action->get_action_name()] = 0;
 164              $actiontypes[$action->get_action_name()] = $action->get_type();
 165          }
 166  
 167          $bulkactions = $this->model->get_target()->bulk_actions($predictions);
 168          foreach ($bulkactions as $action) {
 169              $actionlabels['separated'][$action->get_action_name()] = $action->get_text();
 170              $actionvalues['separated'][$action->get_action_name()] = 0;
 171              $actiontypes[$action->get_action_name()] = $action->get_type();
 172          }
 173  
 174          $actionlabels['grouped'][\core_analytics\action::TYPE_POSITIVE] = get_string('useful', 'analytics');
 175          $actionlabels['grouped'][\core_analytics\action::TYPE_NEUTRAL] = get_string('neutral', 'analytics');
 176          $actionlabels['grouped'][\core_analytics\action::TYPE_NEGATIVE] = get_string('notuseful', 'analytics');
 177  
 178          $actionvalues['grouped'][\core_analytics\action::TYPE_POSITIVE] = 0;
 179          $actionvalues['grouped'][\core_analytics\action::TYPE_NEUTRAL] = 0;
 180          $actionvalues['grouped'][\core_analytics\action::TYPE_NEGATIVE] = 0;
 181  
 182          return [$actionlabels, $actionvalues, $actiontypes];
 183      }
 184  }