. /** * Generator for the gradingforum_guide plugin. * * @package gradingform_guide * @category test * @copyright 2019 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); require_once(__DIR__ . '/guide.php'); require_once(__DIR__ . '/criterion.php'); use tests\gradingform_guide\generator\guide; use tests\gradingform_guide\generator\criterion; /** * Generator for the gradingforum_guide plugintype. * * @package gradingform_guide * @category test * @copyright 2019 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class gradingform_guide_generator extends component_generator_base { /** * Create an instance of a marking guide. * * @param context $context * @param string $component * @param string $area * @param string $name * @param string $description * @param array $criteria The list of criteria to add to the generated guide * @return gradingform_guide_controller */ public function create_instance( context $context, string $component, string $area, string $name, string $description, array $criteria ): gradingform_guide_controller { global $USER; if ($USER->id === 0) { throw new \coding_exception('Creation of a guide must currently be run as a user.'); } // Fetch the controller for this context/component/area. $generator = \testing_util::get_data_generator(); $gradinggenerator = $generator->get_plugin_generator('core_grading'); $controller = $gradinggenerator->create_instance($context, $component, $area, 'guide'); // Generate a definition for the supplied guide. $guide = $this->get_guide($name, $description); foreach ($criteria as $name => $options) { $guide->add_criteria($this->get_criterion( $name, $options['description'], $options['descriptionmarkers'], $options['maxscore'] )); } // Update the controller wih the guide definition. $controller->update_definition($guide->get_definition()); return $controller; } /** * Get a new guide for use with the guide controller. * * Note: This is just a helper class used to build a new definition. It does not persist the data. * * @param string $name * @param string $description * @return generator_guide */ protected function get_guide(string $name, string $description): guide { return new \tests\gradingform_guide\generator\guide($name, $description); } /** * Get a new criterion for use with a guide. * * Note: This is just a helper class used to build a new definition. It does not persist the data. * * @param string $shortname The shortname for the criterion * @param string $description The description for the criterion * @param string $descriptionmarkers The description for the marker for this criterion * @param float $maxscore The maximum score possible for this criterion * @return criterion */ protected function get_criterion( string $shortname, string $description, string $descriptionmarkers, float $maxscore ): criterion { return new criterion($shortname, $description, $descriptionmarkers, $maxscore); } /** * Given a controller instance, fetch the level and criterion information for the specified values. * * @param gradingform_controller $controller * @param string $shortname The shortname to match the criterion on * @return stdClass */ public function get_criterion_for_values(gradingform_controller $controller, string $shortname): ?stdClass { $definition = $controller->get_definition(); $criteria = $definition->guide_criteria; $criterion = array_reduce($criteria, function($carry, $criterion) use ($shortname) { if ($criterion['shortname'] === $shortname) { $carry = (object) $criterion; } return $carry; }, null); return $criterion; } /** * Get submitted form data * * @param gradingform_guide_controller $controller * @param int $itemid * @param array $values A set of array values where the array key is the name of the criterion, and the value is an * array with the desired score, and any remark. */ public function get_submitted_form_data(gradingform_guide_controller $controller, int $itemid, array $values): array { $result = [ 'itemid' => $itemid, 'criteria' => [], ]; foreach ($values as $criterionname => ['score' => $score, 'remark' => $remark]) { $criterion = $this->get_criterion_for_values($controller, $criterionname); $result['criteria'][$criterion->id] = [ 'score' => $score, 'remark' => $remark, ]; } return $result; } /** * Generate a guide controller with sample data required for testing of this class. * * @param context_module $context * @return gradingform_guide_controller */ public function get_test_guide( context_module $context, string $component = 'mod_assign', string $areaname = 'submission' ): gradingform_guide_controller { $generator = \testing_util::get_data_generator(); $gradinggenerator = $generator->get_plugin_generator('core_grading'); $controller = $gradinggenerator->create_instance($context, $component, $areaname, 'guide'); $generator = \testing_util::get_data_generator(); $guidegenerator = $generator->get_plugin_generator('gradingform_guide'); $guide = $guidegenerator->get_guide('testguide', 'Description text'); $guide->add_criteria($guidegenerator->get_criterion( 'Spelling mistakes', 'Full marks will be given for no spelling mistakes.', 'Deduct 5 points per spelling mistake made.', 25 )); $guide->add_criteria($guidegenerator->get_criterion( 'Pictures', 'Full marks will be given for including 3 pictures.', 'Give 5 points for each picture present', 15 )); $controller->update_definition($guide->get_definition()); return $controller; } /** * Fetch a set of sample data. * * @param gradingform_guide_controller $controller * @param int $itemid * @param float $spellingscore * @param string $spellingremark * @param float $picturescore * @param string $pictureremark * @return array */ public function get_test_form_data( gradingform_guide_controller $controller, int $itemid, float $spellingscore, string $spellingremark, float $picturescore, string $pictureremark ): array { $generator = \testing_util::get_data_generator(); $guidegenerator = $generator->get_plugin_generator('gradingform_guide'); return $guidegenerator->get_submitted_form_data($controller, $itemid, [ 'Spelling mistakes' => [ 'score' => $spellingscore, 'remark' => $spellingremark, ], 'Pictures' => [ 'score' => $picturescore, 'remark' => $pictureremark, ], ]); } }