Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 402] [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   * Base class for the options that control what is visible in an {@link quiz_attempts_report}.
  19   *
  20   * @package   mod_quiz
  21   * @copyright 2012 The Open University
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  require_once($CFG->libdir . '/formslib.php');
  29  
  30  
  31  /**
  32   * Base class for the options that control what is visible in an {@link quiz_attempts_report}.
  33   *
  34   * @copyright 2012 The Open University
  35   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class mod_quiz_attempts_report_options {
  38  
  39      /** @var string the report mode. */
  40      public $mode;
  41  
  42      /** @var object the settings for the quiz being reported on. */
  43      public $quiz;
  44  
  45      /** @var object the course module objects for the quiz being reported on. */
  46      public $cm;
  47  
  48      /** @var object the course settings for the course the quiz is in. */
  49      public $course;
  50  
  51      /**
  52       * @var array form field name => corresponding quiz_attempt:: state constant.
  53       */
  54      protected static $statefields = array(
  55          'stateinprogress' => quiz_attempt::IN_PROGRESS,
  56          'stateoverdue'    => quiz_attempt::OVERDUE,
  57          'statefinished'   => quiz_attempt::FINISHED,
  58          'stateabandoned'  => quiz_attempt::ABANDONED,
  59      );
  60  
  61      /**
  62       * @var string quiz_attempts_report::ALL_WITH or quiz_attempts_report::ENROLLED_WITH
  63       *      quiz_attempts_report::ENROLLED_WITHOUT or quiz_attempts_report::ENROLLED_ALL
  64       */
  65      public $attempts = quiz_attempts_report::ENROLLED_WITH;
  66  
  67      /** @var int the currently selected group. 0 if no group is selected. */
  68      public $group = 0;
  69  
  70      /**
  71       * @var array|null of quiz_attempt::IN_PROGRESS, etc. constants. null means
  72       *      no restriction.
  73       */
  74      public $states = array(quiz_attempt::IN_PROGRESS, quiz_attempt::OVERDUE,
  75              quiz_attempt::FINISHED, quiz_attempt::ABANDONED);
  76  
  77      /**
  78       * @var bool whether to show all finished attmepts, or just the one that gave
  79       *      the final grade for the user.
  80       */
  81      public $onlygraded = false;
  82  
  83      /** @var int Number of attempts to show per page. */
  84      public $pagesize = quiz_attempts_report::DEFAULT_PAGE_SIZE;
  85  
  86      /** @var string whether the data should be downloaded in some format, or '' to display it. */
  87      public $download = '';
  88  
  89      /** @var bool whether the current user has permission to see grades. */
  90      public $usercanseegrades;
  91  
  92      /** @var bool whether the report table should have a column of checkboxes. */
  93      public $checkboxcolumn = false;
  94  
  95      /**
  96       * Constructor.
  97       * @param string $mode which report these options are for.
  98       * @param object $quiz the settings for the quiz being reported on.
  99       * @param object $cm the course module objects for the quiz being reported on.
 100       * @param object $coures the course settings for the coures this quiz is in.
 101       */
 102      public function __construct($mode, $quiz, $cm, $course) {
 103          $this->mode   = $mode;
 104          $this->quiz   = $quiz;
 105          $this->cm     = $cm;
 106          $this->course = $course;
 107  
 108          $this->usercanseegrades = quiz_report_should_show_grades($quiz, context_module::instance($cm->id));
 109      }
 110  
 111      /**
 112       * Get the URL parameters required to show the report with these options.
 113       * @return array URL parameter name => value.
 114       */
 115      protected function get_url_params() {
 116          $params = array(
 117              'id'         => $this->cm->id,
 118              'mode'       => $this->mode,
 119              'attempts'   => $this->attempts,
 120              'onlygraded' => $this->onlygraded,
 121          );
 122  
 123          if ($this->states) {
 124              $params['states'] = implode('-', $this->states);
 125          }
 126  
 127          if (groups_get_activity_groupmode($this->cm, $this->course)) {
 128              $params['group'] = $this->group;
 129          }
 130          return $params;
 131      }
 132  
 133      /**
 134       * Get the URL to show the report with these options.
 135       * @return moodle_url the URL.
 136       */
 137      public function get_url() {
 138          return new moodle_url('/mod/quiz/report.php', $this->get_url_params());
 139      }
 140  
 141      /**
 142       * Process the data we get when the settings form is submitted. This includes
 143       * updating the fields of this class, and updating the user preferences
 144       * where appropriate.
 145       * @param object $fromform The data from $mform->get_data() from the settings form.
 146       */
 147      public function process_settings_from_form($fromform) {
 148          $this->setup_from_form_data($fromform);
 149          $this->resolve_dependencies();
 150          $this->update_user_preferences();
 151      }
 152  
 153      /**
 154       * Set up this preferences object using optional_param (using user_preferences
 155       * to set anything not specified by the params.
 156       */
 157      public function process_settings_from_params() {
 158          $this->setup_from_user_preferences();
 159          $this->setup_from_params();
 160          $this->resolve_dependencies();
 161      }
 162  
 163      /**
 164       * Get the current value of the settings to pass to the settings form.
 165       */
 166      public function get_initial_form_data() {
 167          $toform = new stdClass();
 168          $toform->attempts   = $this->attempts;
 169          $toform->onlygraded = $this->onlygraded;
 170          $toform->pagesize   = $this->pagesize;
 171  
 172          if ($this->states) {
 173              foreach (self::$statefields as $field => $state) {
 174                  $toform->$field = in_array($state, $this->states);
 175              }
 176          }
 177  
 178          return $toform;
 179      }
 180  
 181      /**
 182       * Set the fields of this object from the form data.
 183       * @param object $fromform The data from $mform->get_data() from the settings form.
 184       */
 185      public function setup_from_form_data($fromform) {
 186          $this->attempts   = $fromform->attempts;
 187          $this->group      = groups_get_activity_group($this->cm, true);
 188          $this->onlygraded = !empty($fromform->onlygraded);
 189          $this->pagesize   = $fromform->pagesize;
 190  
 191          $this->states = array();
 192          foreach (self::$statefields as $field => $state) {
 193              if (!empty($fromform->$field)) {
 194                  $this->states[] = $state;
 195              }
 196          }
 197      }
 198  
 199      /**
 200       * Set the fields of this object from the URL parameters.
 201       */
 202      public function setup_from_params() {
 203          $this->attempts   = optional_param('attempts', $this->attempts, PARAM_ALPHAEXT);
 204          $this->group      = groups_get_activity_group($this->cm, true);
 205          $this->onlygraded = optional_param('onlygraded', $this->onlygraded, PARAM_BOOL);
 206          $this->pagesize   = optional_param('pagesize', $this->pagesize, PARAM_INT);
 207  
 208          $states = optional_param('states', '', PARAM_ALPHAEXT);
 209          if (!empty($states)) {
 210              $this->states = explode('-', $states);
 211          }
 212  
 213          $this->download   = optional_param('download', $this->download, PARAM_ALPHA);
 214      }
 215  
 216      /**
 217       * Set the fields of this object from the user's preferences.
 218       * (For those settings that are backed by user-preferences).
 219       */
 220      public function setup_from_user_preferences() {
 221          $this->pagesize = get_user_preferences('quiz_report_pagesize', $this->pagesize);
 222      }
 223  
 224      /**
 225       * Update the user preferences so they match the settings in this object.
 226       * (For those settings that are backed by user-preferences).
 227       */
 228      public function update_user_preferences() {
 229          set_user_preference('quiz_report_pagesize', $this->pagesize);
 230      }
 231  
 232      /**
 233       * Check the settings, and remove any 'impossible' combinations.
 234       */
 235      public function resolve_dependencies() {
 236          if ($this->group) {
 237              // Default for when a group is selected.
 238              if ($this->attempts === null || $this->attempts == quiz_attempts_report::ALL_WITH) {
 239                  $this->attempts = quiz_attempts_report::ENROLLED_WITH;
 240              }
 241  
 242          } else if (!$this->group && $this->course->id == SITEID) {
 243              // Force report on front page to show all, unless a group is selected.
 244              $this->attempts = quiz_attempts_report::ALL_WITH;
 245  
 246          } else if (!in_array($this->attempts, array(quiz_attempts_report::ALL_WITH, quiz_attempts_report::ENROLLED_WITH,
 247                  quiz_attempts_report::ENROLLED_WITHOUT, quiz_attempts_report::ENROLLED_ALL))) {
 248              $this->attempts = quiz_attempts_report::ENROLLED_WITH;
 249          }
 250  
 251          $cleanstates = array();
 252          foreach (self::$statefields as $state) {
 253              if (in_array($state, $this->states)) {
 254                  $cleanstates[] = $state;
 255              }
 256          }
 257          $this->states = $cleanstates;
 258          if (count($this->states) == count(self::$statefields)) {
 259              // If all states have been selected, then there is no constraint
 260              // required in the SQL, so clear the array.
 261              $this->states = null;
 262          }
 263  
 264          if (!quiz_report_can_filter_only_graded($this->quiz)) {
 265              // A grading mode like 'average' has been selected, so we cannot do
 266              // the show the attempt that gave the final grade thing.
 267              $this->onlygraded = false;
 268          }
 269  
 270          if ($this->attempts == quiz_attempts_report::ENROLLED_WITHOUT) {
 271              $this->states = null;
 272              $this->onlygraded = false;
 273          }
 274  
 275          if (!$this->is_showing_finished_attempts()) {
 276              $this->onlygraded = false;
 277          }
 278  
 279          if ($this->pagesize < 1) {
 280              $this->pagesize = quiz_attempts_report::DEFAULT_PAGE_SIZE;
 281          }
 282      }
 283  
 284      /**
 285       * Whether the options are such that finished attempts are being shown.
 286       * @return boolean
 287       */
 288      protected function is_showing_finished_attempts() {
 289          return $this->states === null || in_array(quiz_attempt::FINISHED, $this->states);
 290      }
 291  }