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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body