Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.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  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  }