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   * Generator for the gradingforum_guide plugin.
  19   *
  20   * @package    gradingform_guide
  21   * @category   test
  22   * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  require_once (__DIR__ . '/guide.php');
  29  require_once (__DIR__ . '/criterion.php');
  30  
  31  use tests\gradingform_guide\generator\guide;
  32  use tests\gradingform_guide\generator\criterion;
  33  
  34  /**
  35   * Generator for the gradingforum_guide plugintype.
  36   *
  37   * @package    gradingform_guide
  38   * @category   test
  39   * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class gradingform_guide_generator extends component_generator_base {
  43  
  44      /**
  45       * Create an instance of a marking guide.
  46       *
  47       * @param context $context
  48       * @param string $component
  49       * @param string $area
  50       * @param string $name
  51       * @param string $description
  52       * @param array $criteria The list of criteria to add to the generated guide
  53       * @return gradingform_guide_controller
  54       */
  55      public function create_instance(
  56          context $context,
  57          string $component,
  58          string $area,
  59          string $name,
  60          string $description,
  61          array $criteria
  62      ): gradingform_guide_controller {
  63          global $USER;
  64  
  65          if ($USER->id === 0) {
  66              throw new \coding_exception('Creation of a guide must currently be run as a user.');
  67          }
  68  
  69          // Fetch the controller for this context/component/area.
  70          $generator = \testing_util::get_data_generator();
  71          $gradinggenerator = $generator->get_plugin_generator('core_grading');
  72          $controller = $gradinggenerator->create_instance($context, $component, $area, 'guide');
  73  
  74          // Generate a definition for the supplied guide.
  75          $guide = $this->get_guide($name, $description);
  76          foreach ($criteria as $name => $options) {
  77              $guide->add_criteria($this->get_criterion(
  78                  $name,
  79                  $options['description'],
  80                  $options['descriptionmarkers'],
  81                  $options['maxscore']
  82              ));
  83          }
  84  
  85          // Update the controller wih the guide definition.
  86          $controller->update_definition($guide->get_definition());
  87  
  88          return $controller;
  89      }
  90  
  91      /**
  92       * Get a new guide for use with the guide controller.
  93       *
  94       * Note: This is just a helper class used to build a new definition. It does not persist the data.
  95       *
  96       * @param string $name
  97       * @param string $description
  98       * @return generator_guide
  99       */
 100      protected function get_guide(string $name, string $description): guide {
 101          return new \tests\gradingform_guide\generator\guide($name, $description);
 102      }
 103  
 104      /**
 105       * Get a new criterion for use with a guide.
 106       *
 107       * Note: This is just a helper class used to build a new definition. It does not persist the data.
 108       *
 109       * @param string $shortname The shortname for the criterion
 110       * @param string $description The description for the criterion
 111       * @param string $descriptionmarkers The description for the marker for this criterion
 112       * @param float $maxscore The maximum score possible for this criterion
 113       * @return criterion
 114       */
 115      protected function get_criterion(
 116          string $shortname,
 117          string $description,
 118          string $descriptionmarkers,
 119          float $maxscore
 120      ): criterion {
 121          return new criterion($shortname, $description, $descriptionmarkers, $maxscore);
 122      }
 123  
 124      /**
 125       * Given a controller instance, fetch the level and criterion information for the specified values.
 126       *
 127       * @param gradingform_controller $controller
 128       * @param string $shortname The shortname to match the criterion on
 129       * @return stdClass
 130       */
 131      public function get_criterion_for_values(gradingform_controller $controller, string $shortname): ?stdClass {
 132          $definition = $controller->get_definition();
 133          $criteria = $definition->guide_criteria;
 134  
 135          $criterion = array_reduce($criteria, function($carry, $criterion) use ($shortname) {
 136              if ($criterion['shortname'] === $shortname) {
 137                  $carry = (object) $criterion;
 138              }
 139  
 140              return $carry;
 141          }, null);
 142  
 143          return $criterion;
 144      }
 145  
 146      /**
 147       * Get submitted form data
 148       *
 149       * @param gradingform_guide_controller $controller
 150       * @param int $itemid
 151       * @param array $values A set of array values where the array key is the name of the criterion, and the value is an
 152       * array with the desired score, and any remark.
 153       */
 154      public function get_submitted_form_data(gradingform_guide_controller $controller, int $itemid, array $values): array {
 155          $result = [
 156              'itemid' => $itemid,
 157              'criteria' => [],
 158          ];
 159          foreach ($values as $criterionname => ['score' => $score, 'remark' => $remark]) {
 160              $criterion = $this->get_criterion_for_values($controller, $criterionname);
 161              $result['criteria'][$criterion->id] = [
 162                  'score' => $score,
 163                  'remark' => $remark,
 164              ];
 165          }
 166  
 167          return $result;
 168      }
 169  
 170      /**
 171       * Generate a guide controller with sample data required for testing of this class.
 172       *
 173       * @param context_module $context
 174       * @return gradingform_guide_controller
 175       */
 176      public function get_test_guide(
 177          context_module $context,
 178          string $component = 'mod_assign',
 179          string $areaname = 'submission'
 180      ): gradingform_guide_controller {
 181          $generator = \testing_util::get_data_generator();
 182          $gradinggenerator = $generator->get_plugin_generator('core_grading');
 183          $controller = $gradinggenerator->create_instance($context, $component, $areaname, 'guide');
 184  
 185          $generator = \testing_util::get_data_generator();
 186          $guidegenerator = $generator->get_plugin_generator('gradingform_guide');
 187  
 188          $guide = $guidegenerator->get_guide('testguide', 'Description text');
 189  
 190          $guide->add_criteria($guidegenerator->get_criterion(
 191              'Spelling mistakes',
 192              'Full marks will be given for no spelling mistakes.',
 193              'Deduct 5 points per spelling mistake made.',
 194              25
 195          ));
 196          $guide->add_criteria($guidegenerator->get_criterion(
 197              'Pictures',
 198              'Full marks will be given for including 3 pictures.',
 199              'Give 5 points for each picture present',
 200              15
 201          ));
 202          $controller->update_definition($guide->get_definition());
 203  
 204          return $controller;
 205      }
 206  
 207      /**
 208       * Fetch a set of sample data.
 209       *
 210       * @param gradingform_guide_controller $controller
 211       * @param int $itemid
 212       * @param float $spellingscore
 213       * @param string $spellingremark
 214       * @param float $picturescore
 215       * @param string $pictureremark
 216       * @return array
 217       */
 218      public function get_test_form_data(
 219          gradingform_guide_controller $controller,
 220          int $itemid,
 221          float $spellingscore,
 222          string $spellingremark,
 223          float $picturescore,
 224          string $pictureremark
 225      ): array {
 226          $generator = \testing_util::get_data_generator();
 227          $guidegenerator = $generator->get_plugin_generator('gradingform_guide');
 228          return $guidegenerator->get_submitted_form_data($controller, $itemid, [
 229              'Spelling mistakes' => [
 230                  'score' => $spellingscore,
 231                  'remark' => $spellingremark,
 232              ],
 233              'Pictures' => [
 234                  'score' => $picturescore,
 235                  'remark' => $pictureremark,
 236              ],
 237          ]);
 238      }
 239  }