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 namespace mod_quiz\external; 18 19 defined('MOODLE_INTERNAL') || die(); 20 21 require_once($CFG->libdir . '/externallib.php'); 22 require_once($CFG->dirroot . '/question/editlib.php'); 23 require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 24 25 use external_function_parameters; 26 use external_single_structure; 27 use external_value; 28 use external_api; 29 use mod_quiz\question\bank\filter\custom_category_condition; 30 use mod_quiz\quiz_settings; 31 use mod_quiz\structure; 32 33 /** 34 * Add random questions to a quiz. 35 * 36 * @package mod_quiz 37 * @copyright 2022 Catalyst IT Australia Pty Ltd 38 * @author Nathan Nguyen <nathannguyen@catalyst-au.net> 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class add_random_questions extends external_api { 42 43 /** 44 * Parameters for the web service function 45 * 46 * @return external_function_parameters 47 */ 48 public static function execute_parameters(): external_function_parameters { 49 return new external_function_parameters ( 50 [ 51 'cmid' => new external_value(PARAM_INT, 'The cmid of the quiz'), 52 'addonpage' => new external_value(PARAM_INT, 'The page where random questions will be added to'), 53 'randomcount' => new external_value(PARAM_INT, 'Number of random questions'), 54 'filtercondition' => new external_value( 55 PARAM_TEXT, 56 '(Optional) The filter condition used when adding random questions from an existing category. 57 Not required if adding random questions from a new category.', 58 VALUE_DEFAULT, 59 '', 60 ), 61 'newcategory' => new external_value( 62 PARAM_TEXT, 63 '(Optional) The name of a new question category to create and use for the random questions.', 64 VALUE_DEFAULT, 65 '', 66 ), 67 'parentcategory' => new external_value( 68 PARAM_TEXT, 69 '(Optional) The parent of the new question category, if creating one.', 70 VALUE_DEFAULT, 71 0, 72 ), 73 ] 74 ); 75 } 76 77 /** 78 * Add random questions. 79 * 80 * @param int $cmid The cmid of the quiz 81 * @param int $addonpage The page where random questions will be added to 82 * @param int $randomcount Number of random questions 83 * @param string $filtercondition Filter condition 84 * @param string $newcategory add new category 85 * @param string $parentcategory parent category of new category 86 * @return array result 87 */ 88 public static function execute( 89 int $cmid, 90 int $addonpage, 91 int $randomcount, 92 string $filtercondition = '', 93 string $newcategory = '', 94 string $parentcategory = '', 95 ): array { 96 [ 97 'cmid' => $cmid, 98 'addonpage' => $addonpage, 99 'randomcount' => $randomcount, 100 'filtercondition' => $filtercondition, 101 'newcategory' => $newcategory, 102 'parentcategory' => $parentcategory, 103 ] = self::validate_parameters(self::execute_parameters(), [ 104 'cmid' => $cmid, 105 'addonpage' => $addonpage, 106 'randomcount' => $randomcount, 107 'filtercondition' => $filtercondition, 108 'newcategory' => $newcategory, 109 'parentcategory' => $parentcategory, 110 ]); 111 112 // Validate context. 113 $thiscontext = \context_module::instance($cmid); 114 self::validate_context($thiscontext); 115 require_capability('mod/quiz:manage', $thiscontext); 116 117 // If filtercondition is not empty, decode it. Otherwise, set it to empty array. 118 $filtercondition = !empty($filtercondition) ? json_decode($filtercondition, true) : []; 119 120 // Create new category. 121 if (!empty($newcategory)) { 122 $contexts = new \core_question\local\bank\question_edit_contexts($thiscontext); 123 $defaultcategoryobj = question_make_default_categories($contexts->all()); 124 $defaultcategory = $defaultcategoryobj->id . ',' . $defaultcategoryobj->contextid; 125 $qcobject = new \qbank_managecategories\question_category_object( 126 null, 127 new \moodle_url('/'), 128 $contexts->having_one_edit_tab_cap('categories'), 129 $defaultcategoryobj->id, 130 $defaultcategory, 131 null, 132 $contexts->having_cap('moodle/question:add')); 133 $categoryid = $qcobject->add_category($parentcategory, $newcategory, '', true); 134 $filter = [ 135 'category' => [ 136 'jointype' => custom_category_condition::JOINTYPE_DEFAULT, 137 'values' => [$categoryid], 138 'filteroptions' => ['includesubcategories' => false], 139 ] 140 ]; 141 // Generate default filter condition for the random question to be added in the new category. 142 $filtercondition = [ 143 'qpage' => 0, 144 'cat' => "{$categoryid},{$thiscontext->id}", 145 'qperpage' => DEFAULT_QUESTIONS_PER_PAGE, 146 'tabname' => 'questions', 147 'sortdata' => [], 148 'filter' => $filter, 149 ]; 150 } 151 152 // Add random question to the quiz. 153 [$quiz, ] = get_module_from_cmid($cmid); 154 $settings = quiz_settings::create_for_cmid($cmid); 155 $structure = structure::create_for_quiz($settings); 156 $structure->add_random_questions($addonpage, $randomcount, $filtercondition); 157 quiz_delete_previews($quiz); 158 quiz_settings::create($quiz->id)->get_grade_calculator()->recompute_quiz_sumgrades(); 159 160 return ['message' => get_string('addarandomquestion_success', 'mod_quiz')]; 161 } 162 163 /** 164 * Returns description of method result value. 165 * 166 * @return external_value 167 */ 168 public static function execute_returns() { 169 return new external_single_structure([ 170 'message' => new external_value(PARAM_TEXT, 'Message', VALUE_OPTIONAL) 171 ]); 172 } 173 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body